From Craig Silverstein: Add first version of generating error messages

with file name and line number.
This commit is contained in:
Ian Lance Taylor 2007-11-02 23:02:44 +00:00
parent 8942f2584c
commit 5c2c6c957b
8 changed files with 1089 additions and 267 deletions

View File

@ -35,16 +35,6 @@
namespace elfcpp
{
typedef unsigned char Dwarf_uint8;
typedef signed char Dwarf_int8;
typedef uint16_t Dwarf_uint16;
typedef int16_t Dwarf_int16;
typedef uint32_t Dwarf_uint32;
typedef int32_t Dwarf_int32;
typedef uint64_t Dwarf_uint64;
typedef int64_t Dwarf_int64;
// DWARF2 codes.
enum DW_TAG

View File

@ -33,6 +33,7 @@ CCFILES = \
defstd.cc \
dirsearch.cc \
dynobj.cc \
dwarf_reader.cc \
ehframe.cc \
errors.cc \
fileread.cc \
@ -60,6 +61,7 @@ HFILES = \
defstd.h \
dirsearch.h \
dynobj.h \
dwarf_reader.h \
ehframe.h \
errors.h \
fileread.h \

View File

@ -71,14 +71,14 @@ ARFLAGS = cru
libgold_a_AR = $(AR) $(ARFLAGS)
libgold_a_LIBADD =
am__objects_1 = archive.$(OBJEXT) common.$(OBJEXT) defstd.$(OBJEXT) \
dirsearch.$(OBJEXT) dynobj.$(OBJEXT) ehframe.$(OBJEXT) \
errors.$(OBJEXT) fileread.$(OBJEXT) gold.$(OBJEXT) \
gold-threads.$(OBJEXT) layout.$(OBJEXT) merge.$(OBJEXT) \
object.$(OBJEXT) options.$(OBJEXT) output.$(OBJEXT) \
parameters.$(OBJEXT) readsyms.$(OBJEXT) reloc.$(OBJEXT) \
resolve.$(OBJEXT) script.$(OBJEXT) symtab.$(OBJEXT) \
stringpool.$(OBJEXT) target-select.$(OBJEXT) version.$(OBJEXT) \
workqueue.$(OBJEXT)
dirsearch.$(OBJEXT) dynobj.$(OBJEXT) dwarf_reader.$(OBJEXT) \
ehframe.$(OBJEXT) errors.$(OBJEXT) fileread.$(OBJEXT) \
gold.$(OBJEXT) gold-threads.$(OBJEXT) layout.$(OBJEXT) \
merge.$(OBJEXT) object.$(OBJEXT) options.$(OBJEXT) \
output.$(OBJEXT) parameters.$(OBJEXT) readsyms.$(OBJEXT) \
reloc.$(OBJEXT) resolve.$(OBJEXT) script.$(OBJEXT) \
symtab.$(OBJEXT) stringpool.$(OBJEXT) target-select.$(OBJEXT) \
version.$(OBJEXT) workqueue.$(OBJEXT)
am__objects_2 =
am__objects_3 = yyscript.$(OBJEXT)
am_libgold_a_OBJECTS = $(am__objects_1) $(am__objects_2) \
@ -287,6 +287,7 @@ CCFILES = \
defstd.cc \
dirsearch.cc \
dynobj.cc \
dwarf_reader.cc \
ehframe.cc \
errors.cc \
fileread.cc \
@ -314,6 +315,7 @@ HFILES = \
defstd.h \
dirsearch.h \
dynobj.h \
dwarf_reader.h \
ehframe.h \
errors.h \
fileread.h \
@ -462,6 +464,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/defstd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dirsearch.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_reader.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dynobj.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehframe.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errors.Po@am__quote@

529
gold/dwarf_reader.cc Normal file
View File

@ -0,0 +1,529 @@
// dwarf_reader.cc -- parse dwarf2/3 debug information
// Copyright 2007 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// MA 02110-1301, USA.
#include "gold.h"
#include "elfcpp_swap.h"
#include "dwarf.h"
#include "dwarf_reader.h"
namespace {
// Read an unsigned LEB128 number. Each byte contains 7 bits of
// information, plus one bit saying whether the number continues or
// not.
uint64_t
read_unsigned_LEB_128(const unsigned char* buffer, size_t* len)
{
uint64_t result = 0;
size_t num_read = 0;
unsigned int shift = 0;
unsigned char byte;
do
{
byte = *buffer++;
num_read++;
result |= (static_cast<uint64_t>(byte & 0x7f)) << shift;
shift += 7;
}
while (byte & 0x80);
*len = num_read;
return result;
}
// Read a signed LEB128 number. These are like regular LEB128
// numbers, except the last byte may have a sign bit set.
int64_t
read_signed_LEB_128(const unsigned char* buffer, size_t* len)
{
int64_t result = 0;
int shift = 0;
size_t num_read = 0;
unsigned char byte;
do
{
byte = *buffer++;
num_read++;
result |= (static_cast<uint64_t>(byte & 0x7f) << shift);
shift += 7;
}
while (byte & 0x80);
if ((shift < 8 * static_cast<int>(sizeof(result))) && (byte & 0x40))
result |= -((static_cast<int64_t>(1)) << shift);
*len = num_read;
return result;
}
} // End anonymous namespace.
namespace gold {
// This is the format of a DWARF2/3 line state machine that we process
// opcodes using. There is no need for anything outside the lineinfo
// processor to know how this works.
struct LineStateMachine
{
int file_num;
uint64_t address;
int line_num;
int column_num;
unsigned int shndx; // the section address refers to
bool is_stmt; // stmt means statement.
bool basic_block;
bool end_sequence;
};
static void
ResetLineStateMachine(struct LineStateMachine* lsm, bool default_is_stmt)
{
lsm->file_num = 1;
lsm->address = 0;
lsm->line_num = 1;
lsm->column_num = 0;
lsm->shndx = -1;
lsm->is_stmt = default_is_stmt;
lsm->basic_block = false;
lsm->end_sequence = false;
}
// Read the DWARF header.
template<int size, bool big_endian>
const unsigned char*
Dwarf_line_info::read_header_prolog(const unsigned char* lineptr)
{
uint32_t initial_length = elfcpp::Swap<32, big_endian>::readval(lineptr);
lineptr += 4;
// In DWARF2/3, if the initial length is all 1 bits, then the offset
// size is 8 and we need to read the next 8 bytes for the real length.
if (initial_length == 0xffffffff)
{
header_.offset_size = 8;
initial_length = elfcpp::Swap<64, big_endian>::readval(lineptr);
lineptr += 8;
}
else
header_.offset_size = 4;
header_.total_length = initial_length;
gold_assert(lineptr + header_.total_length <= buffer_end_);
header_.version = elfcpp::Swap<16, big_endian>::readval(lineptr);
lineptr += 2;
if (header_.offset_size == 4)
header_.prologue_length = elfcpp::Swap<32, big_endian>::readval(lineptr);
else
header_.prologue_length = elfcpp::Swap<64, big_endian>::readval(lineptr);
lineptr += header_.offset_size;
header_.min_insn_length = *lineptr;
lineptr += 1;
header_.default_is_stmt = *lineptr;
lineptr += 1;
header_.line_base = *reinterpret_cast<const signed char*>(lineptr);
lineptr += 1;
header_.line_range = *lineptr;
lineptr += 1;
header_.opcode_base = *lineptr;
lineptr += 1;
header_.std_opcode_lengths.reserve(header_.opcode_base + 1);
header_.std_opcode_lengths[0] = 0;
for (int i = 1; i < header_.opcode_base; i++)
{
header_.std_opcode_lengths[i] = *lineptr;
lineptr += 1;
}
return lineptr;
}
// The header for a debug_line section is mildly complicated, because
// the line info is very tightly encoded.
const unsigned char*
Dwarf_line_info::read_header_tables(const unsigned char* lineptr)
{
// It is legal for the directory entry table to be empty.
if (*lineptr)
{
int dirindex = 1;
while (*lineptr)
{
const unsigned char* dirname = lineptr;
gold_assert(dirindex == static_cast<int>(directories_.size()));
directories_.push_back(reinterpret_cast<const char*>(dirname));
lineptr += directories_.back().size() + 1;
dirindex++;
}
}
lineptr++;
// It is also legal for the file entry table to be empty.
if (*lineptr)
{
int fileindex = 1;
size_t len;
while (*lineptr)
{
const char* filename = reinterpret_cast<const char*>(lineptr);
lineptr += strlen(filename) + 1;
uint64_t dirindex = read_unsigned_LEB_128(lineptr, &len);
if (dirindex >= directories_.size())
dirindex = 0;
lineptr += len;
read_unsigned_LEB_128(lineptr, &len); // mod_time
lineptr += len;
read_unsigned_LEB_128(lineptr, &len); // filelength
lineptr += len;
gold_assert(fileindex == static_cast<int>(files_.size()));
files_.push_back(std::pair<int, std::string>(dirindex, filename));
fileindex++;
}
}
lineptr++;
return lineptr;
}
// Process a single opcode in the .debug.line structure.
// Templating on size and big_endian would yield more efficient (and
// simpler) code, but would bloat the binary. Speed isn't important
// here.
bool
Dwarf_line_info::process_one_opcode(int size, bool big_endian,
const unsigned char* start,
struct LineStateMachine* lsm,
size_t* len)
{
size_t oplen = 0;
size_t templen;
unsigned char opcode = *start;
oplen++;
start++;
// If the opcode is great than the opcode_base, it is a special
// opcode. Most line programs consist mainly of special opcodes.
if (opcode >= header_.opcode_base)
{
opcode -= header_.opcode_base;
const int advance_address = ((opcode / header_.line_range)
* header_.min_insn_length);
lsm->address += advance_address;
const int advance_line = ((opcode % header_.line_range)
+ header_.line_base);
lsm->line_num += advance_line;
lsm->basic_block = true;
*len = oplen;
return true;
}
// Otherwise, we have the regular opcodes
switch (opcode)
{
case elfcpp::DW_LNS_copy:
lsm->basic_block = false;
*len = oplen;
return true;
case elfcpp::DW_LNS_advance_pc:
{
const uint64_t advance_address
= read_unsigned_LEB_128(start, &templen);
oplen += templen;
lsm->address += header_.min_insn_length * advance_address;
}
break;
case elfcpp::DW_LNS_advance_line:
{
const uint64_t advance_line = read_signed_LEB_128(start, &templen);
oplen += templen;
lsm->line_num += advance_line;
}
break;
case elfcpp::DW_LNS_set_file:
{
const uint64_t fileno = read_unsigned_LEB_128(start, &templen);
oplen += templen;
lsm->file_num = fileno;
}
break;
case elfcpp::DW_LNS_set_column:
{
const uint64_t colno = read_unsigned_LEB_128(start, &templen);
oplen += templen;
lsm->column_num = colno;
}
break;
case elfcpp::DW_LNS_negate_stmt:
lsm->is_stmt = !lsm->is_stmt;
break;
case elfcpp::DW_LNS_set_basic_block:
lsm->basic_block = true;
break;
case elfcpp::DW_LNS_fixed_advance_pc:
{
int advance_address;
if (big_endian)
advance_address = elfcpp::Swap<16, true>::readval(start);
else
advance_address = elfcpp::Swap<16, false>::readval(start);
oplen += 2;
lsm->address += advance_address;
}
break;
case elfcpp::DW_LNS_const_add_pc:
{
const int advance_address = (header_.min_insn_length
* ((255 - header_.opcode_base)
/ header_.line_range));
lsm->address += advance_address;
}
break;
case elfcpp::DW_LNS_extended_op:
{
const uint64_t extended_op_len
= read_unsigned_LEB_128(start, &templen);
start += templen;
oplen += templen + extended_op_len;
const unsigned char extended_op = *start;
start++;
switch (extended_op)
{
case elfcpp::DW_LNE_end_sequence:
lsm->end_sequence = true;
*len = oplen;
return true;
case elfcpp::DW_LNE_set_address:
// FIXME: modify the address based on the reloc
if (size == 32 && big_endian == false)
lsm->address = elfcpp::Swap<32, false>::readval(start);
else if (size == 32 && big_endian == true)
lsm->address = elfcpp::Swap<32, true>::readval(start);
else if (size == 64 && big_endian == false)
lsm->address = elfcpp::Swap<64, false>::readval(start);
else if (size == 64 && big_endian == true)
lsm->address = elfcpp::Swap<64, true>::readval(start);
else
gold_assert(false); // We need to implement more cases, then.
// FIXME: set lsm->shndx from the reloc
lsm->shndx = 1;
break;
case elfcpp::DW_LNE_define_file:
{
const char* filename = reinterpret_cast<const char*>(start);
templen = strlen(filename) + 1;
start += templen;
uint64_t dirindex = read_unsigned_LEB_128(start, &templen);
if (dirindex >= directories_.size())
dirindex = 0;
oplen += templen;
read_unsigned_LEB_128(start, &templen); // mod_time
oplen += templen;
read_unsigned_LEB_128(start, &templen); // filelength
oplen += templen;
files_.push_back(std::pair<int, std::string>(dirindex,
filename));
}
break;
}
}
break;
default:
{
// Ignore unknown opcode silently
for (int i = 0; i < header_.std_opcode_lengths[opcode]; i++)
{
size_t templen;
read_unsigned_LEB_128(start, &templen);
start += templen;
oplen += templen;
}
}
break;
}
*len = oplen;
return false;
}
// Read the debug information at LINEPTR and store it in the line
// number map.
unsigned const char*
Dwarf_line_info::read_lines(int size, bool big_endian,
unsigned const char* lineptr)
{
struct LineStateMachine lsm;
// LENGTHSTART is the place the length field is based on. It is the
// point in the header after the initial length field.
const unsigned char* lengthstart = buffer_;
// In 64 bit dwarf, the initial length is 12 bytes, because of the
// 0xffffffff at the start.
if (header_.offset_size == 8)
lengthstart += 12;
else
lengthstart += 4;
while (lineptr < lengthstart + header_.total_length)
{
ResetLineStateMachine(&lsm, header_.default_is_stmt);
while (!lsm.end_sequence)
{
size_t oplength;
bool add_line = this->process_one_opcode(size, big_endian,
lineptr, &lsm, &oplength);
if (add_line)
{
Offset_to_lineno_entry entry
= { lsm.address, lsm.file_num, lsm.line_num };
line_number_map_[lsm.shndx].push_back(entry);
}
lineptr += oplength;
}
}
return lengthstart + header_.total_length;
}
// Called after all line numbers have been read.
void
Dwarf_line_info::finalize_line_number_map()
{
for (Lineno_map::iterator it = line_number_map_.begin();
it != line_number_map_.end();
++it)
// Each vector needs to be sorted by offset.
sort(it->second.begin(), it->second.end());
}
// Return a string for a file name and line number.
std::string
Dwarf_line_info::addr2line(unsigned int shndx, off_t offset)
{
const Offset_to_lineno_entry lookup_key = { offset, 0, 0 };
std::vector<Offset_to_lineno_entry>& offsets = line_number_map_[shndx];
std::vector<Offset_to_lineno_entry>::const_iterator it
= std::lower_bound(offsets.begin(), offsets.end(), lookup_key);
// If we found an exact match, great, otherwise find the last entry
// before the passed-in offset.
if (it->offset > offset)
{
if (it == offsets.begin())
return "";
--it;
gold_assert(it->offset < offset);
}
// Convert the file_num + line_num into a string.
std::string ret;
gold_assert(it->file_num < static_cast<int>(files_.size()));
const std::pair<int, std::string>& filename_pair = files_[it->file_num];
gold_assert(filename_pair.first < static_cast<int>(directories_.size()));
const std::string& dirname = directories_[filename_pair.first];
const std::string& filename = filename_pair.second;
if (!dirname.empty())
{
ret += dirname;
ret += "/";
}
ret += filename;
if (ret.empty())
ret = "(unknown)";
char buffer[64]; // enough to hold a line number
snprintf(buffer, sizeof(buffer), "%d", it->line_num);
ret += ":";
ret += buffer;
return ret;
}
#ifdef HAVE_TARGET_32_LITTLE
template
const unsigned char*
Dwarf_line_info::read_header_prolog<32, false>(const unsigned char* lineptr);
#endif
#ifdef HAVE_TARGET_32_BIG
template
const unsigned char*
Dwarf_line_info::read_header_prolog<32, true>(const unsigned char* lineptr);
#endif
#ifdef HAVE_TARGET_64_LITTLE
template
const unsigned char*
Dwarf_line_info::read_header_prolog<64, false>(const unsigned char* lineptr);
#endif
#ifdef HAVE_TARGET_64_BIG
template
const unsigned char*
Dwarf_line_info::read_header_prolog<64, true>(const unsigned char* lineptr);
#endif
} // End namespace gold.

150
gold/dwarf_reader.h Normal file
View File

@ -0,0 +1,150 @@
// dwarf_reader.h -- parse dwarf2/3 debug information for gold -*- C++ -*-
// Copyright 2007 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// MA 02110-1301, USA.
#ifndef GOLD_DWARF_READER_H
#define GOLD_DWARF_READER_H
#include <vector>
#include "elfcpp_swap.h"
#include "dwarf.h"
namespace gold
{
struct LineStateMachine;
// This class is used to read the line information from the debugging
// section of an object file.
class Dwarf_line_info
{
public:
// Initializes a .debug_line reader. Buffer and buffer length point
// to the beginning and length of the line information to read.
// Reader is a ByteReader class that has the endianness set
// properly.
Dwarf_line_info(const unsigned char* buffer, off_t buffer_length)
: buffer_(buffer), buffer_end_(buffer + buffer_length),
directories_(1), files_(1)
{ }
// Start processing line info, and populates the offset_map_.
template<int size, bool big_endian>
void
read_line_mappings()
{
while (buffer_ < buffer_end_)
{
const unsigned char* lineptr = buffer_;
lineptr = this->read_header_prolog<size, big_endian>(lineptr);
lineptr = this->read_header_tables(lineptr);
lineptr = this->read_lines(size, big_endian, lineptr);
buffer_ = lineptr;
}
finalize_line_number_map();
}
// Given a section number and an offset, returns the associated
// file and line-number, as a string: "file:lineno". If unable
// to do the mapping, returns the empty string. You must call
// read_line_mappings() before calling this function.
std::string
addr2line(unsigned int shndx, off_t offset);
private:
// Reads the DWARF2/3 header for this line info. Each takes as input
// a starting buffer position, and returns the ending position.
template<int size, bool big_endian>
const unsigned char*
read_header_prolog(const unsigned char* lineptr);
const unsigned char*
read_header_tables(const unsigned char* lineptr);
// Reads the DWARF2/3 line information.
const unsigned char*
read_lines(int size, bool big_endian, const unsigned char* lineptr);
// Process a single line info opcode at START using the state
// machine at LSM. Return true if we should define a line using the
// current state of the line state machine. Place the length of the
// opcode in LEN.
bool
process_one_opcode(int size, bool big_endian,
const unsigned char* start,
struct LineStateMachine* lsm, size_t* len);
// Called after all line number have been read, to ready
// line_number_map_ for calls to addr2line().
void
finalize_line_number_map();
// A DWARF2/3 line info header. This is not the same size as in the
// actual file, as the one in the file may have a 32 bit or 64 bit
// lengths.
struct Dwarf_line_infoHeader
{
off_t total_length;
int version;
off_t prologue_length;
int min_insn_length; // insn stands for instructin
bool default_is_stmt; // stmt stands for statement
signed char line_base;
int line_range;
unsigned char opcode_base;
std::vector<unsigned char> std_opcode_lengths;
int offset_size;
} header_;
// buffer is the buffer for our line info, starting at exactly where
// the line info to read is.
const unsigned char* buffer_;
const unsigned char* const buffer_end_;
// Holds the directories and files as we see them.
std::vector<std::string> directories_;
// The first part is an index into directories_, the second the filename.
std::vector< std::pair<int, std::string> > files_;
// We can't do better than to keep the offsets in a sorted vector.
// Here, offset is the key, and file_num/line_num is the value.
struct Offset_to_lineno_entry
{
off_t offset;
int file_num; // a pointer into files_
int line_num;
// Offsets are unique within a section, so that's a sufficient sort key.
bool operator<(const Offset_to_lineno_entry& that) const
{ return this->offset < that.offset; }
};
// We have a vector of offset->lineno entries for every input section.
typedef Unordered_map<unsigned int, std::vector<Offset_to_lineno_entry> >
Lineno_map;
Lineno_map line_number_map_;
};
} // End namespace gold.
#endif // !defined(GOLD_DWARF_READER_H)

View File

@ -27,6 +27,7 @@
#include <cstdarg>
#include "target-select.h"
#include "dwarf_reader.h"
#include "layout.h"
#include "output.h"
#include "symtab.h"
@ -844,7 +845,7 @@ Sized_relobj<size, big_endian>::get_symbol_location_info(
else if (sym.get_st_shndx() == shndx
&& static_cast<off_t>(sym.get_st_value()) <= offset
&& (static_cast<off_t>(sym.get_st_value() + sym.get_st_size())
>= offset))
> offset))
{
if (sym.get_st_name() > names_size)
info->enclosing_symbol_name = "(invalid)";
@ -907,25 +908,54 @@ template<int size, bool big_endian>
std::string
Relocate_info<size, big_endian>::location(size_t, off_t offset) const
{
// FIXME: We would like to print the following:
// /tmp/foo.o: in function 'fn':foo.c:12: undefined reference to 'xxx'
// We're missing line numbers.
// See if we can get line-number information from debugging sections.
std::string filename;
std::string file_and_lineno; // Better than filename-only, if available.
for (unsigned int shndx = 0; shndx < this->object->shnum(); ++shndx)
if (this->object->section_name(shndx) == ".debug_line")
{
off_t debuglines_size;
const unsigned char* debuglines = this->object->section_contents(
shndx, &debuglines_size, false);
if (debuglines)
{
Dwarf_line_info line_info(debuglines, debuglines_size);
line_info.read_line_mappings<size, big_endian>();
file_and_lineno = line_info.addr2line(this->data_shndx, offset);
}
break;
}
std::string ret(this->object->name());
ret += ':';
Symbol_location_info info;
if (this->object->get_symbol_location_info(this->data_shndx, offset, &info))
{
ret += " in function ";
// We could demangle this name before printing, but we don't
// bother because gcc runs linker output through a demangle
// filter itself. The only advantage to demangling here is if
// someone might call ld directly, rather than via gcc. If we
// did want to demangle, cplus_demangle() is in libiberty.
ret += info.enclosing_symbol_name;
ret += ":";
ret += info.source_file;
filename = info.source_file;
}
if (!file_and_lineno.empty())
ret += file_and_lineno;
else
{
if (!filename.empty())
ret += filename;
ret += "(";
ret += this->object->section_name(this->data_shndx);
char buf[100];
// Offsets into sections have to be positive.
snprintf(buf, sizeof(buf), "+0x%lx", static_cast<long>(offset));
ret += buf;
ret += ")";
}
ret += "(";
ret += this->object->section_name(this->data_shndx);
char buf[100];
// Offsets into sections have to be positive.
snprintf(buf, sizeof(buf), "+0x%lx)", static_cast<long>(offset));
ret += buf;
return ret;
}

View File

@ -6,6 +6,8 @@ defstd.cc
defstd.h
dirsearch.cc
dirsearch.h
dwarf_reader.cc
dwarf_reader.h
dynobj.cc
dynobj.h
ehframe.cc

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-10-13 23:40-0700\n"
"POT-Creation-Date: 2007-11-02 16:01-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -38,7 +38,7 @@ msgstr ""
#: archive.cc:199
#, c-format
msgid "%s: malformed archive header name at %zu\n"
msgid "%s: malformed archive header name at %zu"
msgstr ""
#: archive.cc:224
@ -105,7 +105,7 @@ msgstr ""
msgid "dynamic symbol table name section has wrong type: %u"
msgstr ""
#: dynobj.cc:365 object.cc:428
#: dynobj.cc:365 object.cc:447
#, c-format
msgid "bad section name offset for section %u: %lu"
msgstr ""
@ -169,7 +169,7 @@ msgstr ""
msgid "size of dynamic symbols is not multiple of symbol size"
msgstr ""
#: dynobj.cc:1253
#: dynobj.cc:1265
#, c-format
msgid "symbol %s has undefined version %s"
msgstr ""
@ -229,19 +229,19 @@ msgstr ""
msgid "%s: maximum bytes mapped for read at one time: %llu\n"
msgstr ""
#: fileread.cc:441
#: fileread.cc:442
#, c-format
msgid "cannot find -l%s\n"
msgid "cannot find -l%s"
msgstr ""
#: fileread.cc:468
#: fileread.cc:469
#, c-format
msgid "cannot find %s\n"
msgid "cannot find %s"
msgstr ""
#: fileread.cc:479
#: fileread.cc:480
#, c-format
msgid "cannot open %s: %s\n"
msgid "cannot open %s: %s"
msgstr ""
#: gold.cc:72
@ -249,468 +249,576 @@ msgstr ""
msgid "%s: internal error in %s, at %s:%d\n"
msgstr ""
#: gold.cc:118
#. We had some input files, but we weren't able to open any of
#. them.
#: gold.cc:118 gold.cc:164
msgid "no input files"
msgstr ""
#. We print out just the first .so we see; there may be others.
#: gold.cc:161
#: gold.cc:179
#, c-format
msgid "cannot mix -static with dynamic object %s"
msgstr ""
#: gold-threads.cc:66
msgid "pthead_mutextattr_init failed"
msgstr ""
#: gold-threads.cc:69
msgid "pthread_mutextattr_settype failed"
#, c-format
msgid "pthead_mutextattr_init failed: %s"
msgstr ""
#: gold-threads.cc:73
msgid "pthread_mutex_init failed"
#: gold-threads.cc:72
#, c-format
msgid "pthread_mutextattr_settype failed: %s"
msgstr ""
#: gold-threads.cc:76
msgid "pthread_mutexattr_destroy failed"
#, c-format
msgid "pthread_mutex_init failed: %s"
msgstr ""
#: gold-threads.cc:82
msgid "pthread_mutex_destroy failed"
#: gold-threads.cc:79
#, c-format
msgid "pthread_mutexattr_destroy failed: %s"
msgstr ""
#: gold-threads.cc:89
msgid "pthread_mutex_lock failed"
#: gold-threads.cc:85
#, c-format
msgid "pthread_mutex_destroy failed: %s"
msgstr ""
#: gold-threads.cc:96
msgid "pthread_mutex_unlock failed"
#: gold-threads.cc:92
#, c-format
msgid "pthread_mutex_lock failed: %s"
msgstr ""
#: gold-threads.cc:177
msgid "pthread_cond_init failed"
#: gold-threads.cc:99
#, c-format
msgid "pthread_mutex_unlock failed: %s"
msgstr ""
#: gold-threads.cc:183
msgid "pthread_cond_destroy failed"
#: gold-threads.cc:180
#, c-format
msgid "pthread_cond_init failed: %s"
msgstr ""
#: gold-threads.cc:190
msgid "pthread_cond_wait failed"
#: gold-threads.cc:186
#, c-format
msgid "pthread_cond_destroy failed: %s"
msgstr ""
#: gold-threads.cc:197
msgid "pthread_cond_signal failed"
#: gold-threads.cc:193
#, c-format
msgid "pthread_cond_wait failed: %s"
msgstr ""
#: gold-threads.cc:200
#, c-format
msgid "pthread_cond_signal failed: %s"
msgstr ""
#. FIXME: This needs to specify the location somehow.
#: i386.cc:142 i386.cc:1160 x86_64.cc:1138
#: i386.cc:150 i386.cc:1296 x86_64.cc:162 x86_64.cc:1228
msgid "missing expected TLS relocation"
msgstr ""
#: i386.cc:728 x86_64.cc:700 x86_64.cc:840
#: i386.cc:746 x86_64.cc:709 x86_64.cc:876
#, c-format
msgid "%s: unsupported reloc %u against local symbol"
msgstr ""
#: i386.cc:782
#, c-format
msgid "%s: unexpected reloc %u in object file\n"
msgstr ""
#: i386.cc:870 x86_64.cc:854 x86_64.cc:1024
#, c-format
msgid "%s: unsupported reloc %u against global symbol %s"
msgstr ""
#: i386.cc:974 x86_64.cc:778 x86_64.cc:965
#: i386.cc:840 i386.cc:1070 x86_64.cc:817 x86_64.cc:1055
#, c-format
msgid "%s: unexpected reloc %u in object file"
msgstr ""
#: i386.cc:1070
#: i386.cc:926 x86_64.cc:890 x86_64.cc:1114
#, c-format
msgid "%s: unsupported reloc %u against global symbol %s"
msgstr ""
#: i386.cc:1166
#, c-format
msgid "%s: unsupported RELA reloc section"
msgstr ""
#: i386.cc:1252 x86_64.cc:1315
#: i386.cc:1423 x86_64.cc:1426
#, c-format
msgid "unexpected reloc %u in object file"
msgstr ""
#: i386.cc:1284 i386.cc:1343 i386.cc:1356 i386.cc:1376 i386.cc:1397
#: x86_64.cc:1337 x86_64.cc:1404 x86_64.cc:1413
#: i386.cc:1455 i386.cc:1502 i386.cc:1509 i386.cc:1529 i386.cc:1558
#: x86_64.cc:1447 x86_64.cc:1496 x86_64.cc:1507
#, c-format
msgid "unsupported reloc %u"
msgstr ""
#: i386.cc:1309 x86_64.cc:1362
#: i386.cc:1480 x86_64.cc:1472
msgid "TLS reloc but no TLS segment"
msgstr ""
#: i386.cc:1364
#: i386.cc:1517
msgid "both SUN and GNU model TLS relocations"
msgstr ""
#: merge.cc:254
#: merge.cc:258
msgid "mergeable string section length not multiple of character size"
msgstr ""
#: merge.cc:269
#: merge.cc:274
msgid "entry in mergeable string section not null terminated"
msgstr ""
#: object.cc:49
#: object.cc:50
#, c-format
msgid "%s: unsupported ELF machine number %d"
msgstr ""
#: object.cc:67
#: object.cc:68 script.cc:1222
#, c-format
msgid "%s: %s"
msgstr ""
#: object.cc:102
#: object.cc:103
#, c-format
msgid "section name section has wrong type: %u"
msgstr ""
#: object.cc:243
#: object.cc:244
#, c-format
msgid "invalid symbol table name index: %u"
msgstr ""
#: object.cc:249
#: object.cc:250
#, c-format
msgid "symbol table name section has wrong type: %u"
msgstr ""
#: object.cc:304
#: object.cc:305
#, c-format
msgid "section group %u info %u out of range"
msgstr ""
#: object.cc:322
#: object.cc:323
#, c-format
msgid "symbol %u name offset %u out of range"
msgstr ""
#: object.cc:354
#: object.cc:355
#, c-format
msgid "section %u in section group %u out of range"
msgstr ""
#: object.cc:494
#: object.cc:525
msgid "size of symbols is not multiple of symbol size"
msgstr ""
#. FIXME: Handle SHN_XINDEX.
#: object.cc:584
#: object.cc:615
#, c-format
msgid "unknown section index %u for local symbol %u"
msgstr ""
#: object.cc:593
#: object.cc:624
#, c-format
msgid "local symbol %u section index %u out of range"
msgstr ""
#: object.cc:625
#: object.cc:656
#, c-format
msgid "local symbol %u section name out of range: %u >= %u"
msgstr ""
#: object.cc:805
#: object.cc:892
#, c-format
msgid "%s: incompatible target"
msgstr ""
#: object.cc:872
#: object.cc:994
#, c-format
msgid "%s: unsupported ELF file type %d"
msgstr ""
#: object.cc:891 object.cc:937 object.cc:971
#: object.cc:1013 object.cc:1059 object.cc:1093
#, c-format
msgid "%s: ELF file too short"
msgstr ""
#: object.cc:899
#: object.cc:1021
#, c-format
msgid "%s: invalid ELF version 0"
msgstr ""
#: object.cc:901
#: object.cc:1023
#, c-format
msgid "%s: unsupported ELF version %d"
msgstr ""
#: object.cc:908
#: object.cc:1030
#, c-format
msgid "%s: invalid ELF class 0"
msgstr ""
#: object.cc:914
#: object.cc:1036
#, c-format
msgid "%s: unsupported ELF class %d"
msgstr ""
#: object.cc:921
#: object.cc:1043
#, c-format
msgid "%s: invalid ELF data encoding"
msgstr ""
#: object.cc:927
#: object.cc:1049
#, c-format
msgid "%s: unsupported ELF data encoding %d"
msgstr ""
#: object.cc:947
#: object.cc:1069
#, c-format
msgid "%s: not configured to support 32-bit big-endian object"
msgstr ""
#: object.cc:960
#: object.cc:1082
#, c-format
msgid "%s: not configured to support 32-bit little-endian object"
msgstr ""
#: object.cc:981
#: object.cc:1103
#, c-format
msgid "%s: not configured to support 64-bit big-endian object"
msgstr ""
#: object.cc:994
#: object.cc:1116
#, c-format
msgid "%s: not configured to support 64-bit little-endian object"
msgstr ""
#: options.cc:139
#: options.cc:142
#, c-format
msgid "%s: unable to parse script file %s\n"
msgstr ""
#: options.cc:170
#, c-format
msgid ""
"Usage: %s [options] file...\n"
"Options:\n"
msgstr ""
#: options.cc:309
msgid "Search for library LIBNAME"
msgstr ""
#: options.cc:310
msgid "-lLIBNAME, --library LIBNAME"
msgstr ""
#: options.cc:312
msgid "Start a library search group"
msgstr ""
#: options.cc:314
msgid "End a library search group"
msgstr ""
#: options.cc:316
msgid "Export all dynamic symbols"
msgstr ""
#: options.cc:318
msgid "Set dynamic linker path"
msgstr ""
#: options.cc:319
msgid "-I PROGRAM, --dynamic-linker PROGRAM"
msgstr ""
#: options.cc:321
msgid "Add directory to search path"
msgstr ""
#: options.cc:322
msgid "-L DIR, --library-path DIR"
msgstr ""
#: options.cc:324
msgid "Ignored for compatibility"
msgstr ""
#: options.cc:326
msgid "Optimize output file size"
msgstr ""
#: options.cc:327
msgid "-O level"
msgstr ""
#: options.cc:329
msgid "Set output file name"
msgstr ""
#: options.cc:330
msgid "-o FILE, --output FILE"
msgstr ""
#: options.cc:332
msgid "Generate relocatable output"
msgstr ""
#: options.cc:334
msgid "Add DIR to runtime search path"
msgstr ""
#: options.cc:335
msgid "-R DIR, -rpath DIR"
msgstr ""
#: options.cc:337
msgid "Strip all symbols"
msgstr ""
#: options.cc:339
msgid "Strip debugging information"
msgstr ""
#: options.cc:341
msgid "Create exception frame header"
msgstr ""
#: options.cc:344
msgid "Add DIR to link time shared library search path"
msgstr ""
#: options.cc:345
msgid "--rpath-link DIR"
msgstr ""
#: options.cc:347
msgid "Generate shared library"
msgstr ""
#: options.cc:349
msgid "Do not link against shared libraries"
msgstr ""
#: options.cc:351
msgid "Print resource usage statistics"
msgstr ""
#: options.cc:353
msgid "Set target system root directory"
msgstr ""
#: options.cc:354
msgid "--sysroot DIR"
msgstr ""
#: options.cc:356
msgid "Only set DT_NEEDED for dynamic libs if used"
msgstr ""
#: options.cc:359
#: options.cc:344
msgid "Always DT_NEEDED for dynamic libs (default)"
msgstr ""
#: options.cc:362
msgid "Include all archive contents"
#: options.cc:347
msgid "-l searches for shared libraries"
msgstr ""
#: options.cc:351
msgid "-l does not search for shared libraries"
msgstr ""
#: options.cc:354
msgid "Bind defined symbols locally"
msgstr ""
#: options.cc:356
msgid "Export all dynamic symbols"
msgstr ""
#: options.cc:358
msgid "Create exception frame header"
msgstr ""
#: options.cc:360
msgid "Set dynamic linker path"
msgstr ""
#: options.cc:361
msgid "-I PROGRAM, --dynamic-linker PROGRAM"
msgstr ""
#: options.cc:363
msgid "Search for library LIBNAME"
msgstr ""
#: options.cc:364
msgid "-lLIBNAME, --library LIBNAME"
msgstr ""
#: options.cc:366
msgid "Include only needed archive contents"
msgid "Add directory to search path"
msgstr ""
#: options.cc:367
msgid "-L DIR, --library-path DIR"
msgstr ""
#: options.cc:369
msgid "Report usage information"
msgid "Ignored for compatibility"
msgstr ""
#: options.cc:371
msgid "Set output file name"
msgstr ""
#: options.cc:372
msgid "-o FILE, --output FILE"
msgstr ""
#: options.cc:374
msgid "Optimize output file size"
msgstr ""
#: options.cc:375
msgid "-O level"
msgstr ""
#: options.cc:377
msgid "Generate relocatable output"
msgstr ""
#: options.cc:379
msgid "Add DIR to runtime search path"
msgstr ""
#: options.cc:380
msgid "-R DIR, -rpath DIR"
msgstr ""
#: options.cc:383
msgid "Add DIR to link time shared library search path"
msgstr ""
#: options.cc:384
msgid "--rpath-link DIR"
msgstr ""
#: options.cc:386
msgid "Strip all symbols"
msgstr ""
#: options.cc:388
msgid "Strip debugging information"
msgstr ""
#: options.cc:390
msgid "Generate shared library"
msgstr ""
#: options.cc:392
msgid "Do not link against shared libraries"
msgstr ""
#: options.cc:394
msgid "Print resource usage statistics"
msgstr ""
#: options.cc:396
msgid "Set target system root directory"
msgstr ""
#: options.cc:397
msgid "--sysroot DIR"
msgstr ""
#: options.cc:398
msgid "Set the address of the .text section"
msgstr ""
#: options.cc:399
msgid "-Ttext ADDRESS"
msgstr ""
#. This must come after -Ttext since it's a prefix of it.
#: options.cc:402
msgid "Read linker script"
msgstr ""
#: options.cc:403
msgid "-T FILE, --script FILE"
msgstr ""
#: options.cc:405
msgid "Run the linker multi-threaded"
msgstr ""
#: options.cc:407
msgid "Do not run the linker multi-threaded"
msgstr ""
#: options.cc:409
msgid "Number of threads to use"
msgstr ""
#: options.cc:410
msgid "--thread-count COUNT"
msgstr ""
#: options.cc:413
msgid "Number of threads to use in initial pass"
msgstr ""
#: options.cc:414
msgid "--thread-count-initial COUNT"
msgstr ""
#: options.cc:417
msgid "Number of threads to use in middle pass"
msgstr ""
#: options.cc:418
msgid "--thread-count-middle COUNT"
msgstr ""
#: options.cc:421
msgid "Number of threads to use in final pass"
msgstr ""
#: options.cc:422
msgid "--thread-count-final COUNT"
msgstr ""
#: options.cc:425
msgid "Include all archive contents"
msgstr ""
#: options.cc:429
msgid "Include only needed archive contents"
msgstr ""
#: options.cc:434
msgid ""
"Subcommands as follows:\n"
" -z execstack Mark output as requiring executable stack\n"
" -z noexecstack Mark output as not requiring executable stack"
msgstr ""
#: options.cc:437
msgid "-z SUBCOMMAND"
msgstr ""
#: options.cc:440
msgid "Start a library search group"
msgstr ""
#: options.cc:442
msgid "End a library search group"
msgstr ""
#: options.cc:444
msgid "Report usage information"
msgstr ""
#: options.cc:446
msgid "Report version information"
msgstr ""
#: options.cc:576
#: options.cc:518
#, c-format
msgid "%s: unrecognized -z subcommand: %s\n"
msgstr ""
#: options.cc:698
msgid "unexpected argument"
msgstr ""
#: options.cc:583 options.cc:634 options.cc:735
#: options.cc:705 options.cc:757 options.cc:838
msgid "missing argument"
msgstr ""
#: options.cc:596 options.cc:643
#: options.cc:718 options.cc:766
msgid "unknown option"
msgstr ""
#: options.cc:651
#: options.cc:784
#, c-format
msgid "%s: missing group end"
msgid "%s: missing group end\n"
msgstr ""
#: options.cc:748
#: options.cc:912
msgid "may not nest groups"
msgstr ""
#: options.cc:758
#: options.cc:922
msgid "group end without group start"
msgstr ""
#: options.cc:768
#: options.cc:932
#, c-format
msgid "%s: use the --help option for usage information\n"
msgstr ""
#: options.cc:777
#: options.cc:941
#, c-format
msgid "%s: %s: %s\n"
msgstr ""
#: options.cc:786
#: options.cc:950
#, c-format
msgid "%s: -%c: %s\n"
msgstr ""
#: output.cc:1031
#: options.h:338
#, c-format
msgid "%s: invalid argument to -Ttext: %s\n"
msgstr ""
#: options.h:351
#, c-format
msgid "%s: invalid thread count: %s\n"
msgstr ""
#: output.cc:1038
#, c-format
msgid "invalid alignment %lu for section \"%s\""
msgstr ""
#: output.cc:1697
#: output.cc:1703
#, c-format
msgid "%s: open: %s"
msgstr ""
#: output.cc:1702
#: output.cc:1708
#, c-format
msgid "%s: lseek: %s"
msgstr ""
#: output.cc:1705
#: output.cc:1711
#, c-format
msgid "%s: write: %s"
msgstr ""
#: output.cc:1711
#: output.cc:1717
#, c-format
msgid "%s: mmap: %s"
msgstr ""
#: output.cc:1721
#: output.cc:1727
#, c-format
msgid "%s: munmap: %s\n"
msgid "%s: munmap: %s"
msgstr ""
#: output.cc:1725
#: output.cc:1731
#, c-format
msgid "%s: close: %s"
msgstr ""
#: readsyms.cc:94
#: readsyms.cc:147
#, c-format
msgid "%s: file is empty"
msgstr ""
#: readsyms.cc:129
#: readsyms.cc:182
#, c-format
msgid "%s: ordinary object found in input group"
msgstr ""
#. Here we have to handle any other input file types we need.
#: readsyms.cc:177
#: readsyms.cc:230
#, c-format
msgid "%s: not an object or archive"
msgstr ""
@ -735,53 +843,66 @@ msgstr ""
msgid "reloc section %u size %lu uneven"
msgstr ""
#: resolve.cc:136
#: resolve.cc:165
#, c-format
msgid "%s: invalid STB_LOCAL symbol %s in external symbols"
msgstr ""
#: resolve.cc:142
#: resolve.cc:171
#, c-format
msgid "%s: unsupported symbol binding %d for symbol %s"
msgstr ""
#. Two definitions of the same symbol.
#. FIXME: Report locations.
#: resolve.cc:280
#. FIXME: Do a better job of reporting locations.
#: resolve.cc:310
#, c-format
msgid "multiple definition of %s\n"
msgid "%s: multiple definition of %s"
msgstr ""
#: script.cc:1169
#, c-format
msgid "%s: %s\n"
#: resolve.cc:311 resolve.cc:316
msgid "command line"
msgstr ""
#: symtab.cc:517
#: resolve.cc:313
#, c-format
msgid "%s: previous definition here"
msgstr ""
#. There are some options that we could handle here--e.g.,
#. -lLIBRARY. Should we bother?
#: script.cc:1326
#, c-format
msgid ""
"%s: Ignoring command OPTION; OPTION is only valid for scripts specified via -"
"T"
msgstr ""
#: symtab.cc:540
#, c-format
msgid "bad global symbol name offset %u at %zu"
msgstr ""
#: symtab.cc:595
#: symtab.cc:618
msgid "too few symbol versions"
msgstr ""
#: symtab.cc:614
#: symtab.cc:647
#, c-format
msgid "bad symbol name offset %u at %zu"
msgstr ""
#: symtab.cc:665
#: symtab.cc:701
#, c-format
msgid "versym for symbol %zu out of range: %u"
msgstr ""
#: symtab.cc:672
#: symtab.cc:709
#, c-format
msgid "versym for symbol %zu has no name: %u"
msgstr ""
#: symtab.cc:1241 symtab.cc:1444
#: symtab.cc:1427 symtab.cc:1630
#, c-format
msgid "%s: unsupported symbol section 0x%x"
msgstr ""
@ -791,11 +912,11 @@ msgstr ""
msgid "reloc has bad offset %zu"
msgstr ""
#: tls.h:58 x86_64.cc:1538
#: tls.h:58
msgid "TLS relocation out of range"
msgstr ""
#: tls.h:72 x86_64.cc:1551
#: tls.h:72
msgid "TLS relocation against invalid instruction"
msgstr ""
@ -814,17 +935,12 @@ msgid ""
"This program has absolutely no warranty.\n"
msgstr ""
#. FIXME: This needs to specify the location somehow.
#: x86_64.cc:154
msgid "missing expected TLS relocation\n"
msgstr ""
#: x86_64.cc:1047
#: x86_64.cc:1137
#, c-format
msgid "%s: unsupported REL reloc section"
msgstr ""
#: x86_64.cc:1389
#: x86_64.cc:1535
#, c-format
msgid "unsupported reloc type %u"
msgstr ""