This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[nonworking patch] gold/arm: define $a/$d markers in .plt
- From: Roland McGrath <mcgrathr at google dot com>
- To: binutils at sourceware dot org
- Date: Tue, 17 Apr 2012 14:38:47 -0700
- Subject: [nonworking patch] gold/arm: define $a/$d markers in .plt
When gold generates an ARM .plt section, it fails to define any magic
marker symbols (local symbols named $a or $d). These are necessary to
make objdump -d disassemble the .plt contents rather than just showing
them as data words.
I tried to hack it in with the following. But it produces:
./gold/ld-new: error: invalid STB_LOCAL symbol in external symbols
./gold/ld-new: error: unsupported symbol binding 0
./gold/ld-new: error: linker defined: multiple definition of '$a'
./gold/ld-new: command line: previous definition here
This is not surprising given the comment on define_in_output_data:
// Define a special symbol based on an Output_data. It is a
// multiple definition error if this symbol is already defined.
To wit, if I comment out the second and third add_marker_symbol calls, it
produces a $a symbol correctly. That is better than nothing, since there
is only one non-instruction word of .plt and it's easier to read around the
inappropriate disassembly of that one word than the inappropriate lack of
disassembly of all the other words. But we really should emit all three
symbols, like BFD ld does.
A quick glance through the Symbol_table methods did not enclue me as to how
to define multiple locals of the same name. Suggestions?
Thanks,
Roland
diff --git a/gold/arm.cc b/gold/arm.cc
index dc6e64a..b3a8c2e 100644
--- a/gold/arm.cc
+++ b/gold/arm.cc
@@ -7223,8 +7223,29 @@ class Output_data_plt_arm : public Output_section_data
get_plt_entry_size()
{ return sizeof(plt_entry); }
+ // Define marker symbols at the start of the PLT so that
+ // objdump will know to disassemble it as ARM instructions.
+ void
+ add_marker_symbols(Output_section* os, Symbol_table* symtab)
+ {
+ this->add_marker_symbol(os, symtab, 0, false);
+ this->add_marker_symbol(os, symtab, 16, true);
+ this->add_marker_symbol(os, symtab, 20, false);
+ }
+
protected:
void
+ add_marker_symbol(Output_section* os, Symbol_table* symtab,
+ Arm_address offset, bool is_data)
+ {
+ symtab->define_in_output_data(is_data ? "$d" : "$a", NULL,
+ Symbol_table::PREDEFINED, os,
+ offset, 0,
+ elfcpp::STT_NOTYPE, elfcpp::STB_LOCAL,
+ elfcpp::STV_DEFAULT, 0, false, false);
+ }
+
+ void
do_adjust_output_section(Output_section* os);
// Write to a map file.
@@ -7430,10 +7451,13 @@ Target_arm<big_endian>::make_plt_entry(Symbol_table* symtab, Layout* layout,
this->got_section(symtab, layout);
this->plt_ = new Output_data_plt_arm<big_endian>(layout, this->got_plt_);
- layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
- (elfcpp::SHF_ALLOC
- | elfcpp::SHF_EXECINSTR),
+
+ Output_section* os = layout->add_output_section_data
+ (".plt", elfcpp::SHT_PROGBITS,
+ (elfcpp::SHF_ALLOC | elfcpp::SHF_EXECINSTR),
this->plt_, ORDER_PLT, false);
+
+ this->plt_->add_marker_symbols(os, symtab);
}
this->plt_->add_entry(gsym);
}