diff options
author | Ian Lance Taylor <ian@airs.com> | 2008-07-24 01:24:50 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2008-07-24 01:24:50 +0000 |
commit | 7f649c59d1863d01c97a920232f86fdacaac2199 (patch) | |
tree | ed62d752731b1efa605213a8605ae0682ac3fadc | |
parent | 94c16cb98879da70426f93eda449c3c2388ce761 (diff) | |
download | gdb-7f649c59d1863d01c97a920232f86fdacaac2199.zip gdb-7f649c59d1863d01c97a920232f86fdacaac2199.tar.gz gdb-7f649c59d1863d01c97a920232f86fdacaac2199.tar.bz2 |
PR 6658
* object.h (Merged_symbol_value::value): Do our best to handle a
negative addend.
-rw-r--r-- | gold/ChangeLog | 4 | ||||
-rw-r--r-- | gold/object.h | 29 |
2 files changed, 30 insertions, 3 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index dca8a51..a145899 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,5 +1,9 @@ 2008-07-23 Ian Lance Taylor <iant@google.com> + PR 6658 + * object.h (Merged_symbol_value::value): Do our best to handle a + negative addend. + PR 6647 * script.cc (Version_script_info::get_versions): Don't add empty version tag to return value. diff --git a/gold/object.h b/gold/object.h index 7334492..8ddd689 100644 --- a/gold/object.h +++ b/gold/object.h @@ -822,13 +822,36 @@ class Merged_symbol_value Value value(const Relobj* object, unsigned int input_shndx, Value addend) const { - Value input_offset = this->input_value_ + addend; + // This is a relocation against a section symbol. ADDEND is the + // offset in the section. The result should be the start of some + // merge area. If the object file wants something else, it should + // use a regular symbol rather than a section symbol. + // Unfortunately, PR 6658 shows a case in which the object file + // refers to the section symbol, but uses a negative ADDEND to + // compensate for a PC relative reloc. We can't handle the + // general case. However, we can handle the special case of a + // negative addend, by assuming that it refers to the start of the + // section. Of course, that means that we have to guess when + // ADDEND is negative. It is normal to see a 32-bit value here + // even when the template parameter size is 64, as 64-bit object + // file formats have 32-bit relocations. We know this is a merge + // section, so we know it has to fit into memory. So we assume + // that we won't see a value larger than a large 32-bit unsigned + // value. This will break objects with very very large merge + // sections; they probably break in other ways anyhow. + Value input_offset = this->input_value_; + if (addend < 0xffffff00) + { + input_offset += addend; + addend = 0; + } typename Output_addresses::const_iterator p = this->output_addresses_.find(input_offset); if (p != this->output_addresses_.end()) - return p->second; + return p->second + addend; - return this->value_from_output_section(object, input_shndx, input_offset); + return (this->value_from_output_section(object, input_shndx, input_offset) + + addend); } private: |