mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 18:14:13 +08:00
From Craig Silverstein: Add first version of generating error messages
with file name and line number.
This commit is contained in:
parent
8942f2584c
commit
5c2c6c957b
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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
529
gold/dwarf_reader.cc
Normal 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
150
gold/dwarf_reader.h
Normal 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)
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,8 @@ defstd.cc
|
||||
defstd.h
|
||||
dirsearch.cc
|
||||
dirsearch.h
|
||||
dwarf_reader.cc
|
||||
dwarf_reader.h
|
||||
dynobj.cc
|
||||
dynobj.h
|
||||
ehframe.cc
|
||||
|
592
gold/po/gold.pot
592
gold/po/gold.pot
@ -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 ""
|
||||
|
Loading…
Reference in New Issue
Block a user