From Craig Silverstein: Add support for compressing .debug_str section.
This commit is contained in:
parent
71195202df
commit
9a0910c33e
@ -30,6 +30,7 @@ noinst_LIBRARIES = libgold.a
|
|||||||
CCFILES = \
|
CCFILES = \
|
||||||
archive.cc \
|
archive.cc \
|
||||||
common.cc \
|
common.cc \
|
||||||
|
compressed_output.cc \
|
||||||
defstd.cc \
|
defstd.cc \
|
||||||
dirsearch.cc \
|
dirsearch.cc \
|
||||||
dynobj.cc \
|
dynobj.cc \
|
||||||
@ -59,6 +60,7 @@ CCFILES = \
|
|||||||
HFILES = \
|
HFILES = \
|
||||||
archive.h \
|
archive.h \
|
||||||
common.h \
|
common.h \
|
||||||
|
compressed_output.h \
|
||||||
defstd.h \
|
defstd.h \
|
||||||
dirsearch.h \
|
dirsearch.h \
|
||||||
dynobj.h \
|
dynobj.h \
|
||||||
|
@ -70,7 +70,8 @@ AR = ar
|
|||||||
ARFLAGS = cru
|
ARFLAGS = cru
|
||||||
libgold_a_AR = $(AR) $(ARFLAGS)
|
libgold_a_AR = $(AR) $(ARFLAGS)
|
||||||
libgold_a_LIBADD =
|
libgold_a_LIBADD =
|
||||||
am__objects_1 = archive.$(OBJEXT) common.$(OBJEXT) defstd.$(OBJEXT) \
|
am__objects_1 = archive.$(OBJEXT) common.$(OBJEXT) \
|
||||||
|
compressed_output.$(OBJEXT) defstd.$(OBJEXT) \
|
||||||
dirsearch.$(OBJEXT) dynobj.$(OBJEXT) dwarf_reader.$(OBJEXT) \
|
dirsearch.$(OBJEXT) dynobj.$(OBJEXT) dwarf_reader.$(OBJEXT) \
|
||||||
ehframe.$(OBJEXT) errors.$(OBJEXT) fileread.$(OBJEXT) \
|
ehframe.$(OBJEXT) errors.$(OBJEXT) fileread.$(OBJEXT) \
|
||||||
gold.$(OBJEXT) gold-threads.$(OBJEXT) layout.$(OBJEXT) \
|
gold.$(OBJEXT) gold-threads.$(OBJEXT) layout.$(OBJEXT) \
|
||||||
@ -152,6 +153,7 @@ CATOBJEXT = @CATOBJEXT@
|
|||||||
CC = @CC@
|
CC = @CC@
|
||||||
CCDEPMODE = @CCDEPMODE@
|
CCDEPMODE = @CCDEPMODE@
|
||||||
CFLAGS = @CFLAGS@
|
CFLAGS = @CFLAGS@
|
||||||
|
CPP = @CPP@
|
||||||
CPPFLAGS = @CPPFLAGS@
|
CPPFLAGS = @CPPFLAGS@
|
||||||
CXX = @CXX@
|
CXX = @CXX@
|
||||||
CXXCPP = @CXXCPP@
|
CXXCPP = @CXXCPP@
|
||||||
@ -285,6 +287,7 @@ noinst_LIBRARIES = libgold.a
|
|||||||
CCFILES = \
|
CCFILES = \
|
||||||
archive.cc \
|
archive.cc \
|
||||||
common.cc \
|
common.cc \
|
||||||
|
compressed_output.cc \
|
||||||
defstd.cc \
|
defstd.cc \
|
||||||
dirsearch.cc \
|
dirsearch.cc \
|
||||||
dynobj.cc \
|
dynobj.cc \
|
||||||
@ -314,6 +317,7 @@ CCFILES = \
|
|||||||
HFILES = \
|
HFILES = \
|
||||||
archive.h \
|
archive.h \
|
||||||
common.h \
|
common.h \
|
||||||
|
compressed_output.h \
|
||||||
defstd.h \
|
defstd.h \
|
||||||
dirsearch.h \
|
dirsearch.h \
|
||||||
dynobj.h \
|
dynobj.h \
|
||||||
@ -465,6 +469,7 @@ distclean-compile:
|
|||||||
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/pread.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/pread.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/archive.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/archive.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compressed_output.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/defstd.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)/dirsearch.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_reader.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_reader.Po@am__quote@
|
||||||
|
267
gold/compressed_output.cc
Normal file
267
gold/compressed_output.cc
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
// compressed_output.cc -- manage compressed output sections for gold
|
||||||
|
|
||||||
|
// 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"
|
||||||
|
|
||||||
|
#ifdef HAVE_ZLIB_H
|
||||||
|
#include <zlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "compressed_output.h"
|
||||||
|
#include "parameters.h"
|
||||||
|
|
||||||
|
namespace gold
|
||||||
|
{
|
||||||
|
|
||||||
|
// Compress UNCOMPRESSED_DATA of size UNCOMPRESSED_SIZE. Returns true
|
||||||
|
// if it successfully compressed, false if it failed for any reason
|
||||||
|
// (including not having zlib support in the library). If it returns
|
||||||
|
// true, it allocates memory for the compressed data using new, and
|
||||||
|
// sets *COMPRESSED_DATA and *COMPRESSED_SIZE to appropriate values.
|
||||||
|
|
||||||
|
static bool
|
||||||
|
zlib_compress(const char* uncompressed_data, unsigned long uncompressed_size,
|
||||||
|
char** compressed_data, unsigned long* compressed_size)
|
||||||
|
{
|
||||||
|
#ifndef HAVE_ZLIB_H
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
*compressed_size = uncompressed_size + uncompressed_size / 1000 + 128;
|
||||||
|
*compressed_data = new char[*compressed_size];
|
||||||
|
|
||||||
|
int compress_level;
|
||||||
|
if (parameters->optimization_level() >= 1)
|
||||||
|
compress_level = 9;
|
||||||
|
else
|
||||||
|
compress_level = 1;
|
||||||
|
|
||||||
|
int rc = compress2(reinterpret_cast<Bytef*>(*compressed_data),
|
||||||
|
compressed_size,
|
||||||
|
reinterpret_cast<const Bytef*>(uncompressed_data),
|
||||||
|
uncompressed_size,
|
||||||
|
compress_level);
|
||||||
|
if (rc == Z_OK)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete[] *compressed_data;
|
||||||
|
*compressed_data = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif // #ifdef HAVE_ZLIB_H
|
||||||
|
}
|
||||||
|
|
||||||
|
// After compressing an output section, we rename it from foo to
|
||||||
|
// foo.zlib.nnnn, where nnnn is the uncompressed size of the section.
|
||||||
|
|
||||||
|
static std::string
|
||||||
|
zlib_compressed_suffix(unsigned long uncompressed_size)
|
||||||
|
{
|
||||||
|
char size_string[64];
|
||||||
|
snprintf(size_string, sizeof(size_string), "%lu", uncompressed_size);
|
||||||
|
return std::string(".zlib.") + size_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Class Output_compressed_section_data.
|
||||||
|
|
||||||
|
// Add an input section. In this case, we just keep track of the sections.
|
||||||
|
|
||||||
|
bool
|
||||||
|
Output_compressed_section_data::do_add_input_section(Relobj* obj,
|
||||||
|
unsigned int shndx)
|
||||||
|
{
|
||||||
|
this->objects_.push_back(Object_entry(obj, shndx));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the final data size of a compressed section. This is where
|
||||||
|
// we actually compress the section data.
|
||||||
|
|
||||||
|
void
|
||||||
|
Output_compressed_section_data::set_final_data_size()
|
||||||
|
{
|
||||||
|
// FIXME: assert that relocations have already been applied.
|
||||||
|
|
||||||
|
off_t uncompressed_size = 0;
|
||||||
|
for (std::vector<Object_entry>::iterator it = this->objects_.begin();
|
||||||
|
it != this->objects_.end();
|
||||||
|
++it)
|
||||||
|
{
|
||||||
|
it->contents
|
||||||
|
= it->object->section_contents(it->shndx, &it->length, false);
|
||||||
|
uncompressed_size += it->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// (Try to) compress the data.
|
||||||
|
unsigned long compressed_size;
|
||||||
|
char* uncompressed_data = new char[uncompressed_size];
|
||||||
|
off_t pos = 0;
|
||||||
|
for (std::vector<Object_entry>::const_iterator it = this->objects_.begin();
|
||||||
|
it != this->objects_.end();
|
||||||
|
++it)
|
||||||
|
{
|
||||||
|
memcpy(uncompressed_data + pos,
|
||||||
|
reinterpret_cast<const char*>(it->contents),
|
||||||
|
it->length);
|
||||||
|
pos += it->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
if (options_.zlib_compress_debug_sections())
|
||||||
|
success = zlib_compress(uncompressed_data, uncompressed_size,
|
||||||
|
&this->data_, &compressed_size);
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
delete[] uncompressed_data;
|
||||||
|
this->set_data_size(compressed_size);
|
||||||
|
this->new_section_name_ = zlib_compressed_suffix(uncompressed_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gold_warning(_("Not compressing section data: zlib error"));
|
||||||
|
gold_assert(this->data_ == NULL);
|
||||||
|
this->data_ = uncompressed_data;
|
||||||
|
this->set_data_size(uncompressed_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change the name of the output section to reflect it's compressed.
|
||||||
|
// The layout routines call into this right before finalizing the
|
||||||
|
// shstrtab.
|
||||||
|
|
||||||
|
const char*
|
||||||
|
Output_compressed_section_data::do_modified_output_section_name(
|
||||||
|
const char* name)
|
||||||
|
{
|
||||||
|
// This mean we never compressed the data.
|
||||||
|
if (this->new_section_name_.empty())
|
||||||
|
return NULL;
|
||||||
|
this->new_section_name_ = std::string(name) + this->new_section_name_;
|
||||||
|
return this->new_section_name_.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write out a compressed section. If we couldn't compress, we just
|
||||||
|
// write it out as normal, uncompressed data.
|
||||||
|
|
||||||
|
void
|
||||||
|
Output_compressed_section_data::do_write(Output_file* of)
|
||||||
|
{
|
||||||
|
unsigned char* uview = of->get_output_view(this->offset(),
|
||||||
|
this->data_size());
|
||||||
|
char* view = reinterpret_cast<char*>(uview);
|
||||||
|
memcpy(view, this->data_, this->data_size());
|
||||||
|
of->write_output_view(this->offset(), this->data_size(), uview);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Class Output_compressed_string.
|
||||||
|
|
||||||
|
// Add an input section. We don't do anything special here.
|
||||||
|
|
||||||
|
template<typename Char_type>
|
||||||
|
bool
|
||||||
|
Output_compressed_string<Char_type>::do_add_input_section(Relobj* object,
|
||||||
|
unsigned int shndx)
|
||||||
|
{
|
||||||
|
return Output_merge_string<Char_type>::do_add_input_section(object, shndx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the final data size of a compressed section. This is where
|
||||||
|
// we actually compress the section data.
|
||||||
|
|
||||||
|
template<typename Char_type>
|
||||||
|
void
|
||||||
|
Output_compressed_string<Char_type>::set_final_data_size()
|
||||||
|
{
|
||||||
|
// First let the superclass finalize all its data, then write it to
|
||||||
|
// a buffer.
|
||||||
|
unsigned long uncompressed_size = this->finalize_merged_data();
|
||||||
|
char* uncompressed_data = new char[uncompressed_size];
|
||||||
|
this->stringpool_to_buffer(uncompressed_data, uncompressed_size);
|
||||||
|
|
||||||
|
// (Try to) compress the data.
|
||||||
|
unsigned long compressed_size;
|
||||||
|
if (options_.zlib_compress_debug_sections()
|
||||||
|
&& zlib_compress(uncompressed_data, uncompressed_size,
|
||||||
|
&this->compressed_data_, &compressed_size))
|
||||||
|
{
|
||||||
|
this->set_data_size(compressed_size);
|
||||||
|
// Save some memory.
|
||||||
|
this->clear_stringpool();
|
||||||
|
// We will be renaming the section to name.zlib.uncompressed_size.
|
||||||
|
this->new_section_name_ = zlib_compressed_suffix(uncompressed_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->compressed_data_ = NULL;
|
||||||
|
this->set_data_size(uncompressed_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] uncompressed_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change the name of the output section to reflect it's compressed.
|
||||||
|
// The layout routines call into this right before finalizing the
|
||||||
|
// shstrtab.
|
||||||
|
|
||||||
|
template<typename Char_type>
|
||||||
|
const char*
|
||||||
|
Output_compressed_string<Char_type>::do_modified_output_section_name(
|
||||||
|
const char* name)
|
||||||
|
{
|
||||||
|
// This mean we never compressed the data
|
||||||
|
if (this->new_section_name_.empty())
|
||||||
|
return NULL;
|
||||||
|
this->new_section_name_ = std::string(name) + this->new_section_name_;
|
||||||
|
return this->new_section_name_.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write out a compressed string section. If we couldn't compress,
|
||||||
|
// we just write out the normal string section.
|
||||||
|
|
||||||
|
template<typename Char_type>
|
||||||
|
void
|
||||||
|
Output_compressed_string<Char_type>::do_write(Output_file* of)
|
||||||
|
{
|
||||||
|
if (this->compressed_data_ == NULL)
|
||||||
|
Output_merge_string<Char_type>::do_write(of);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned char* uview = of->get_output_view(this->offset(),
|
||||||
|
this->data_size());
|
||||||
|
char* view = reinterpret_cast<char*>(uview);
|
||||||
|
memcpy(view, this->compressed_data_, this->data_size());
|
||||||
|
of->write_output_view(this->offset(), this->data_size(), uview);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instantiate the templates we need.
|
||||||
|
|
||||||
|
template
|
||||||
|
class Output_compressed_string<char>;
|
||||||
|
|
||||||
|
template
|
||||||
|
class Output_compressed_string<uint16_t>;
|
||||||
|
|
||||||
|
template
|
||||||
|
class Output_compressed_string<uint32_t>;
|
||||||
|
|
||||||
|
} // End namespace gold.
|
137
gold/compressed_output.h
Normal file
137
gold/compressed_output.h
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
// compressed_output.h -- compressed output sections 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.
|
||||||
|
|
||||||
|
// We support compressing .debug_* sections on output. (And,
|
||||||
|
// potentially one day, other sections.) This is a form of
|
||||||
|
// relaxation. This file adds support for merging and emitting the
|
||||||
|
// compressed sections.
|
||||||
|
|
||||||
|
#ifndef GOLD_COMPRESSED_OUTPUT_H
|
||||||
|
#define GOLD_COMPRESSED_OUTPUT_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "output.h"
|
||||||
|
#include "merge.h"
|
||||||
|
|
||||||
|
namespace gold
|
||||||
|
{
|
||||||
|
|
||||||
|
class General_options;
|
||||||
|
|
||||||
|
// This is used for compressing a section before emitting it in the
|
||||||
|
// output file. This only works for unloaded sections, since it
|
||||||
|
// assumes the final section contents are available at
|
||||||
|
// set_final_data_size() time. For loaded sections (those that end up
|
||||||
|
// in segments), this is not true; relocations are applied after
|
||||||
|
// set_final_data_size() is called. However, for unloaded sections,
|
||||||
|
// we can -- and do -- postpone calling finalize_data_size() until
|
||||||
|
// after relocations are applies.
|
||||||
|
|
||||||
|
class Output_compressed_section_data : public Output_section_data
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Output_compressed_section_data(uint64_t addralign,
|
||||||
|
const General_options& options)
|
||||||
|
: Output_section_data(addralign), options_(options), data_(NULL)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Add an input section.
|
||||||
|
bool
|
||||||
|
do_add_input_section(Relobj* object, unsigned int shndx);
|
||||||
|
|
||||||
|
// Set the final data size.
|
||||||
|
void
|
||||||
|
set_final_data_size();
|
||||||
|
|
||||||
|
// Change the name of the output section to reflect it's compressed.
|
||||||
|
const char*
|
||||||
|
do_modified_output_section_name(const char* name);
|
||||||
|
|
||||||
|
// Write the data to the file.
|
||||||
|
void
|
||||||
|
do_write(Output_file*);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Object_entry
|
||||||
|
{
|
||||||
|
Relobj* object;
|
||||||
|
unsigned int shndx;
|
||||||
|
const unsigned char* contents;
|
||||||
|
off_t length;
|
||||||
|
|
||||||
|
Object_entry(Relobj* o, unsigned int s)
|
||||||
|
: object(o), shndx(s), contents(NULL), length(0)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
const General_options& options_;
|
||||||
|
std::vector<Object_entry> objects_;
|
||||||
|
char* data_;
|
||||||
|
std::string new_section_name_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is a special case for when the output section is a string
|
||||||
|
// section and does not have any relocations to apply to it.
|
||||||
|
|
||||||
|
template<typename Char_type>
|
||||||
|
class Output_compressed_string : public Output_merge_string<Char_type>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Output_compressed_string(uint64_t addralign,
|
||||||
|
const General_options& options)
|
||||||
|
: Output_merge_string<Char_type>(addralign),
|
||||||
|
options_(options), compressed_data_(NULL)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
~Output_compressed_string()
|
||||||
|
{ delete[] compressed_data_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Add an input section.
|
||||||
|
bool
|
||||||
|
do_add_input_section(Relobj* object, unsigned int shndx);
|
||||||
|
|
||||||
|
// Set the final data size. Also compresses the buffer.
|
||||||
|
void
|
||||||
|
set_final_data_size();
|
||||||
|
|
||||||
|
// Change the name of the output section to reflect it's compressed.
|
||||||
|
const char*
|
||||||
|
do_modified_output_section_name(const char* name);
|
||||||
|
|
||||||
|
// Write the data to the file.
|
||||||
|
void
|
||||||
|
do_write(Output_file*);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const General_options& options_;
|
||||||
|
char* compressed_data_;
|
||||||
|
// This is just a buffer to store the section name in "permanent" storage.
|
||||||
|
std::string new_section_name_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // End namespace gold.
|
||||||
|
|
||||||
|
#endif // !defined(GOLD_COMPRESSED_OUTPUT_H)
|
@ -67,6 +67,9 @@
|
|||||||
/* Define to 1 if you have the <unistd.h> header file. */
|
/* Define to 1 if you have the <unistd.h> header file. */
|
||||||
#undef HAVE_UNISTD_H
|
#undef HAVE_UNISTD_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <zlib.h> header file. */
|
||||||
|
#undef HAVE_ZLIB_H
|
||||||
|
|
||||||
/* Name of package */
|
/* Name of package */
|
||||||
#undef PACKAGE
|
#undef PACKAGE
|
||||||
|
|
||||||
|
1028
gold/configure
vendored
1028
gold/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -202,6 +202,9 @@ AC_SUBST(LFS_CXXFLAGS)
|
|||||||
|
|
||||||
AC_REPLACE_FUNCS(pread)
|
AC_REPLACE_FUNCS(pread)
|
||||||
|
|
||||||
|
# Link in zlib if we can. This allows us to write compressed sections.
|
||||||
|
AC_SEARCH_LIBS(zlibVersion, z, [AC_CHECK_HEADERS(zlib.h)])
|
||||||
|
|
||||||
AC_LANG_PUSH(C++)
|
AC_LANG_PUSH(C++)
|
||||||
|
|
||||||
AC_CHECK_HEADERS(tr1/unordered_set tr1/unordered_map)
|
AC_CHECK_HEADERS(tr1/unordered_set tr1/unordered_map)
|
||||||
|
@ -393,7 +393,7 @@ Output_section*
|
|||||||
Layout::make_output_section(const char* name, elfcpp::Elf_Word type,
|
Layout::make_output_section(const char* name, elfcpp::Elf_Word type,
|
||||||
elfcpp::Elf_Xword flags)
|
elfcpp::Elf_Xword flags)
|
||||||
{
|
{
|
||||||
Output_section* os = new Output_section(name, type, flags);
|
Output_section* os = new Output_section(this->options_, name, type, flags);
|
||||||
this->section_list_.push_back(os);
|
this->section_list_.push_back(os);
|
||||||
|
|
||||||
if ((flags & elfcpp::SHF_ALLOC) == 0)
|
if ((flags & elfcpp::SHF_ALLOC) == 0)
|
||||||
@ -710,7 +710,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab)
|
|||||||
|
|
||||||
// Set the file offsets of all the non-data sections which don't
|
// Set the file offsets of all the non-data sections which don't
|
||||||
// have to wait for the input sections.
|
// have to wait for the input sections.
|
||||||
off = this->set_section_offsets(off, false);
|
off = this->set_section_offsets(off, BEFORE_INPUT_SECTIONS_PASS);
|
||||||
|
|
||||||
// Now that all sections have been created, set the section indexes.
|
// Now that all sections have been created, set the section indexes.
|
||||||
shndx = this->set_section_indexes(shndx);
|
shndx = this->set_section_indexes(shndx);
|
||||||
@ -1059,7 +1059,7 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
|
|||||||
// segment.
|
// segment.
|
||||||
|
|
||||||
off_t
|
off_t
|
||||||
Layout::set_section_offsets(off_t off, bool after_input_sections)
|
Layout::set_section_offsets(off_t off, Layout::Section_offset_pass pass)
|
||||||
{
|
{
|
||||||
for (Section_list::iterator p = this->unattached_section_list_.begin();
|
for (Section_list::iterator p = this->unattached_section_list_.begin();
|
||||||
p != this->unattached_section_list_.end();
|
p != this->unattached_section_list_.end();
|
||||||
@ -1069,8 +1069,17 @@ Layout::set_section_offsets(off_t off, bool after_input_sections)
|
|||||||
if (*p == this->symtab_section_)
|
if (*p == this->symtab_section_)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((*p)->after_input_sections() != after_input_sections)
|
if (pass == BEFORE_INPUT_SECTIONS_PASS
|
||||||
continue;
|
&& (*p)->after_input_sections())
|
||||||
|
continue;
|
||||||
|
else if (pass == AFTER_INPUT_SECTIONS_PASS
|
||||||
|
&& (!(*p)->after_input_sections()
|
||||||
|
|| (*p)->type() == elfcpp::SHT_STRTAB))
|
||||||
|
continue;
|
||||||
|
else if (pass == STRTAB_AFTER_INPUT_SECTIONS_PASS
|
||||||
|
&& (!(*p)->after_input_sections()
|
||||||
|
|| (*p)->type() != elfcpp::SHT_STRTAB))
|
||||||
|
continue;
|
||||||
|
|
||||||
off = align_address(off, (*p)->addralign());
|
off = align_address(off, (*p)->addralign());
|
||||||
(*p)->set_file_offset(off);
|
(*p)->set_file_offset(off);
|
||||||
@ -1080,6 +1089,19 @@ Layout::set_section_offsets(off_t off, bool after_input_sections)
|
|||||||
return off;
|
return off;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow any section not associated with a segment to change its
|
||||||
|
// output section name at the last minute.
|
||||||
|
|
||||||
|
void
|
||||||
|
Layout::modify_section_names()
|
||||||
|
{
|
||||||
|
for (Section_list::iterator p = this->unattached_section_list_.begin();
|
||||||
|
p != this->unattached_section_list_.end();
|
||||||
|
++p)
|
||||||
|
if ((*p)->maybe_modify_output_section_name())
|
||||||
|
this->namepool_.add((*p)->name(), true, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
// Set the section indexes of all the sections not associated with a
|
// Set the section indexes of all the sections not associated with a
|
||||||
// segment.
|
// segment.
|
||||||
|
|
||||||
@ -1883,9 +1905,19 @@ void
|
|||||||
Layout::write_sections_after_input_sections(Output_file* of)
|
Layout::write_sections_after_input_sections(Output_file* of)
|
||||||
{
|
{
|
||||||
// Determine the final section offsets, and thus the final output
|
// Determine the final section offsets, and thus the final output
|
||||||
// file size.
|
// file size. Note we finalize the .shstrab last, to allow the
|
||||||
|
// after_input_section sections to modify their section-names before
|
||||||
|
// writing.
|
||||||
off_t off = this->output_file_size_;
|
off_t off = this->output_file_size_;
|
||||||
off = this->set_section_offsets(off, true);
|
off = this->set_section_offsets(off, AFTER_INPUT_SECTIONS_PASS);
|
||||||
|
|
||||||
|
// Determine the final section names as well (at least, for sections
|
||||||
|
// that we haven't written yet).
|
||||||
|
this->modify_section_names();
|
||||||
|
|
||||||
|
// Now that we've finalized the names, we can finalize the shstrab.
|
||||||
|
off = this->set_section_offsets(off, STRTAB_AFTER_INPUT_SECTIONS_PASS);
|
||||||
|
|
||||||
if (off > this->output_file_size_)
|
if (off > this->output_file_size_)
|
||||||
{
|
{
|
||||||
of->resize(off);
|
of->resize(off);
|
||||||
|
@ -342,9 +342,25 @@ class Layout
|
|||||||
set_segment_offsets(const Target*, Output_segment*, unsigned int* pshndx);
|
set_segment_offsets(const Target*, Output_segment*, unsigned int* pshndx);
|
||||||
|
|
||||||
// Set the final file offsets of all the sections not associated
|
// Set the final file offsets of all the sections not associated
|
||||||
// with a segment.
|
// with a segment. We set section offsets in three passes: the
|
||||||
|
// first handles all allocated sections, the second sections that
|
||||||
|
// can be handled after input-sections are processed, and the last
|
||||||
|
// the late-bound STRTAB sections (probably only shstrtab, which is
|
||||||
|
// the one we care about because it holds section names).
|
||||||
|
enum Section_offset_pass
|
||||||
|
{
|
||||||
|
BEFORE_INPUT_SECTIONS_PASS,
|
||||||
|
AFTER_INPUT_SECTIONS_PASS,
|
||||||
|
STRTAB_AFTER_INPUT_SECTIONS_PASS
|
||||||
|
};
|
||||||
off_t
|
off_t
|
||||||
set_section_offsets(off_t, bool after_input_sections);
|
set_section_offsets(off_t, Section_offset_pass pass);
|
||||||
|
|
||||||
|
// We also allow any section not associated with a segment to change
|
||||||
|
// its output section name at the last minute. Compressed sections
|
||||||
|
// use this to embed compression info in their name.
|
||||||
|
void
|
||||||
|
modify_section_names();
|
||||||
|
|
||||||
// Set the final section indexes of all the sections not associated
|
// Set the final section indexes of all the sections not associated
|
||||||
// with a segment. Returns the next unused index.
|
// with a segment. Returns the next unused index.
|
||||||
|
@ -496,13 +496,12 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the final data size of a merged string section. This is where
|
// Finalize the mappings from the input sections to the output
|
||||||
// we finalize the mappings from the input sections to the output
|
// section, and return the final data size.
|
||||||
// section.
|
|
||||||
|
|
||||||
template<typename Char_type>
|
template<typename Char_type>
|
||||||
void
|
off_t
|
||||||
Output_merge_string<Char_type>::set_final_data_size()
|
Output_merge_string<Char_type>::finalize_merged_data()
|
||||||
{
|
{
|
||||||
this->stringpool_.set_string_offsets();
|
this->stringpool_.set_string_offsets();
|
||||||
|
|
||||||
@ -513,10 +512,18 @@ Output_merge_string<Char_type>::set_final_data_size()
|
|||||||
this->add_mapping(p->object, p->shndx, p->offset, p->length,
|
this->add_mapping(p->object, p->shndx, p->offset, p->length,
|
||||||
this->stringpool_.get_offset(p->string));
|
this->stringpool_.get_offset(p->string));
|
||||||
|
|
||||||
this->set_data_size(this->stringpool_.get_strtab_size());
|
|
||||||
|
|
||||||
// Save some memory.
|
// Save some memory.
|
||||||
this->merged_strings_.clear();
|
this->merged_strings_.clear();
|
||||||
|
|
||||||
|
return this->stringpool_.get_strtab_size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Char_type>
|
||||||
|
void
|
||||||
|
Output_merge_string<Char_type>::set_final_data_size()
|
||||||
|
{
|
||||||
|
const off_t final_data_size = this->finalize_merged_data();
|
||||||
|
this->set_data_size(final_data_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write out a merged string section.
|
// Write out a merged string section.
|
||||||
|
16
gold/merge.h
16
gold/merge.h
@ -209,10 +209,16 @@ class Output_merge_string : public Output_merge_base
|
|||||||
this->stringpool_.set_no_zero_null();
|
this->stringpool_.set_no_zero_null();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
// Add an input section.
|
// Add an input section.
|
||||||
bool
|
bool
|
||||||
do_add_input_section(Relobj* object, unsigned int shndx);
|
do_add_input_section(Relobj* object, unsigned int shndx);
|
||||||
|
|
||||||
|
// Do all the final processing after the input sections are read in.
|
||||||
|
// Returns the final data size.
|
||||||
|
off_t
|
||||||
|
finalize_merged_data();
|
||||||
|
|
||||||
// Set the final data size.
|
// Set the final data size.
|
||||||
void
|
void
|
||||||
set_final_data_size();
|
set_final_data_size();
|
||||||
@ -221,6 +227,16 @@ class Output_merge_string : public Output_merge_base
|
|||||||
void
|
void
|
||||||
do_write(Output_file*);
|
do_write(Output_file*);
|
||||||
|
|
||||||
|
// Writes the stringpool to a buffer.
|
||||||
|
void
|
||||||
|
stringpool_to_buffer(char* buffer, size_t buffer_size)
|
||||||
|
{ this->stringpool_.write_to_buffer(buffer, buffer_size); }
|
||||||
|
|
||||||
|
// Clears all the data in the stringpool, to save on memory.
|
||||||
|
void
|
||||||
|
clear_stringpool()
|
||||||
|
{ stringpool_.clear(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// As we see input sections, we build a mapping from object, section
|
// As we see input sections, we build a mapping from object, section
|
||||||
// index and offset to strings.
|
// index and offset to strings.
|
||||||
|
@ -376,6 +376,17 @@ options::Command_line_options::options[] =
|
|||||||
&Position_dependent_options::set_static_search),
|
&Position_dependent_options::set_static_search),
|
||||||
GENERAL_NOARG('\0', "Bsymbolic", N_("Bind defined symbols locally"),
|
GENERAL_NOARG('\0', "Bsymbolic", N_("Bind defined symbols locally"),
|
||||||
NULL, ONE_DASH, &General_options::set_symbolic),
|
NULL, ONE_DASH, &General_options::set_symbolic),
|
||||||
|
#ifdef HAVE_ZLIB_H
|
||||||
|
# define ZLIB_STR ",zlib"
|
||||||
|
#else
|
||||||
|
# define ZLIB_STR ""
|
||||||
|
#endif
|
||||||
|
GENERAL_ARG('\0', "compress-debug-sections",
|
||||||
|
N_("Compress .debug_* sections in the output file "
|
||||||
|
"(default is none)"),
|
||||||
|
N_("--compress-debug-sections=[none" ZLIB_STR "]"),
|
||||||
|
TWO_DASHES,
|
||||||
|
&General_options::set_compress_debug_symbols),
|
||||||
GENERAL_NOARG('\0', "demangle", N_("Demangle C++ symbols in log messages"),
|
GENERAL_NOARG('\0', "demangle", N_("Demangle C++ symbols in log messages"),
|
||||||
NULL, TWO_DASHES, &General_options::set_demangle),
|
NULL, TWO_DASHES, &General_options::set_demangle),
|
||||||
GENERAL_NOARG('\0', "no-demangle",
|
GENERAL_NOARG('\0', "no-demangle",
|
||||||
@ -525,6 +536,7 @@ General_options::General_options()
|
|||||||
strip_(STRIP_NONE),
|
strip_(STRIP_NONE),
|
||||||
allow_shlib_undefined_(false),
|
allow_shlib_undefined_(false),
|
||||||
symbolic_(false),
|
symbolic_(false),
|
||||||
|
compress_debug_sections_(NO_COMPRESSION),
|
||||||
detect_odr_violations_(false),
|
detect_odr_violations_(false),
|
||||||
create_eh_frame_hdr_(false),
|
create_eh_frame_hdr_(false),
|
||||||
rpath_(),
|
rpath_(),
|
||||||
|
@ -150,8 +150,8 @@ class General_options
|
|||||||
strip_debug() const
|
strip_debug() const
|
||||||
{ return this->strip_ == STRIP_ALL || this->strip_ == STRIP_DEBUG; }
|
{ return this->strip_ == STRIP_ALL || this->strip_ == STRIP_DEBUG; }
|
||||||
|
|
||||||
// -Sgdb: strip only debugging information that's not used by
|
// --strip-debug-gdb: strip only debugging information that's not
|
||||||
// gdb (at least, for gdb versions <= 6.7).
|
// used by gdb (at least, for gdb versions <= 6.7).
|
||||||
bool
|
bool
|
||||||
strip_debug_gdb() const
|
strip_debug_gdb() const
|
||||||
{ return this->strip_debug() || this->strip_ == STRIP_DEBUG_UNUSED_BY_GDB; }
|
{ return this->strip_debug() || this->strip_ == STRIP_DEBUG_UNUSED_BY_GDB; }
|
||||||
@ -167,6 +167,17 @@ class General_options
|
|||||||
symbolic() const
|
symbolic() const
|
||||||
{ return this->symbolic_; }
|
{ return this->symbolic_; }
|
||||||
|
|
||||||
|
// --compress-debug-sections: compress .debug_* sections in the
|
||||||
|
// output file using the given compression method. This is useful
|
||||||
|
// when the tools (such as gdb) support compressed sections.
|
||||||
|
bool
|
||||||
|
compress_debug_sections() const
|
||||||
|
{ return this->compress_debug_sections_ != NO_COMPRESSION; }
|
||||||
|
|
||||||
|
bool
|
||||||
|
zlib_compress_debug_sections() const
|
||||||
|
{ return this->compress_debug_sections_ == ZLIB_COMPRESSION; }
|
||||||
|
|
||||||
// --demangle: demangle C++ symbols in our log messages.
|
// --demangle: demangle C++ symbols in our log messages.
|
||||||
bool
|
bool
|
||||||
demangle() const
|
demangle() const
|
||||||
@ -288,6 +299,13 @@ class General_options
|
|||||||
EXECSTACK_NO
|
EXECSTACK_NO
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// What compression method to use
|
||||||
|
enum CompressionMethod
|
||||||
|
{
|
||||||
|
NO_COMPRESSION,
|
||||||
|
ZLIB_COMPRESSION,
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
set_export_dynamic()
|
set_export_dynamic()
|
||||||
{ this->export_dynamic_ = true; }
|
{ this->export_dynamic_ = true; }
|
||||||
@ -342,6 +360,19 @@ class General_options
|
|||||||
set_symbolic()
|
set_symbolic()
|
||||||
{ this->symbolic_ = true; }
|
{ this->symbolic_ = true; }
|
||||||
|
|
||||||
|
void set_compress_debug_symbols(const char* arg)
|
||||||
|
{
|
||||||
|
if (strcmp(arg, "none") == 0)
|
||||||
|
this->compress_debug_sections_ = NO_COMPRESSION;
|
||||||
|
#ifdef HAVE_ZLIB_H
|
||||||
|
else if (strcmp(arg, "zlib") == 0)
|
||||||
|
this->compress_debug_sections_ = ZLIB_COMPRESSION;
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
gold_fatal(_("Unsupported argument to --compress-debug-symbols: %s"),
|
||||||
|
arg);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
set_demangle()
|
set_demangle()
|
||||||
{ this->demangle_ = true; }
|
{ this->demangle_ = true; }
|
||||||
@ -476,6 +507,7 @@ class General_options
|
|||||||
Strip strip_;
|
Strip strip_;
|
||||||
bool allow_shlib_undefined_;
|
bool allow_shlib_undefined_;
|
||||||
bool symbolic_;
|
bool symbolic_;
|
||||||
|
CompressionMethod compress_debug_sections_;
|
||||||
bool demangle_;
|
bool demangle_;
|
||||||
bool detect_odr_violations_;
|
bool detect_odr_violations_;
|
||||||
bool create_eh_frame_hdr_;
|
bool create_eh_frame_hdr_;
|
||||||
|
112
gold/output.cc
112
gold/output.cc
@ -32,6 +32,7 @@
|
|||||||
#include "libiberty.h" // for unlink_if_ordinary()
|
#include "libiberty.h" // for unlink_if_ordinary()
|
||||||
|
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
|
#include "compressed_output.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
#include "reloc.h"
|
#include "reloc.h"
|
||||||
@ -1033,9 +1034,11 @@ Output_section::Input_section::write(Output_file* of)
|
|||||||
|
|
||||||
// Construct an Output_section. NAME will point into a Stringpool.
|
// Construct an Output_section. NAME will point into a Stringpool.
|
||||||
|
|
||||||
Output_section::Output_section(const char* name, elfcpp::Elf_Word type,
|
Output_section::Output_section(const General_options& options,
|
||||||
|
const char* name, elfcpp::Elf_Word type,
|
||||||
elfcpp::Elf_Xword flags)
|
elfcpp::Elf_Xword flags)
|
||||||
: name_(name),
|
: options_(options),
|
||||||
|
name_(name),
|
||||||
addralign_(0),
|
addralign_(0),
|
||||||
entsize_(0),
|
entsize_(0),
|
||||||
link_section_(NULL),
|
link_section_(NULL),
|
||||||
@ -1079,6 +1082,22 @@ Output_section::set_entsize(uint64_t v)
|
|||||||
gold_assert(this->entsize_ == v);
|
gold_assert(this->entsize_ == v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sometimes we compress sections. This is typically done for
|
||||||
|
// sections that are not part of normal program execution (such as
|
||||||
|
// .debug_* sections), and where the readers of these sections know
|
||||||
|
// how to deal with compressed sections. (To make it easier for them,
|
||||||
|
// we will rename the ouput section in such cases from .foo to
|
||||||
|
// .foo.zlib.nnnn, where nnnn is the uncompressed size.) This routine
|
||||||
|
// doesn't say for certain whether we'll compress -- it depends on
|
||||||
|
// commandline options as well -- just whether this section is a
|
||||||
|
// candidate for compression.
|
||||||
|
|
||||||
|
static bool
|
||||||
|
is_compressible_section(const char* secname)
|
||||||
|
{
|
||||||
|
return (strncmp(secname, ".debug", sizeof(".debug") - 1) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
// Add the input section SHNDX, with header SHDR, named SECNAME, in
|
// Add the input section SHNDX, with header SHDR, named SECNAME, in
|
||||||
// OBJECT, to the Output_section. RELOC_SHNDX is the index of a
|
// OBJECT, to the Output_section. RELOC_SHNDX is the index of a
|
||||||
// relocation section which applies to this section, or 0 if none, or
|
// relocation section which applies to this section, or 0 if none, or
|
||||||
@ -1126,7 +1145,8 @@ Output_section::add_input_section(Sized_relobj<size, big_endian>* object,
|
|||||||
&& reloc_shndx == 0)
|
&& reloc_shndx == 0)
|
||||||
{
|
{
|
||||||
if (this->add_merge_input_section(object, shndx, sh_flags,
|
if (this->add_merge_input_section(object, shndx, sh_flags,
|
||||||
entsize, addralign))
|
entsize, addralign,
|
||||||
|
is_compressible_section(secname)))
|
||||||
{
|
{
|
||||||
// Tell the relocation routines that they need to call the
|
// Tell the relocation routines that they need to call the
|
||||||
// output_offset method to determine the final address.
|
// output_offset method to determine the final address.
|
||||||
@ -1213,7 +1233,8 @@ Output_section::add_output_merge_section(Output_section_data* posd,
|
|||||||
bool
|
bool
|
||||||
Output_section::add_merge_input_section(Relobj* object, unsigned int shndx,
|
Output_section::add_merge_input_section(Relobj* object, unsigned int shndx,
|
||||||
uint64_t flags, uint64_t entsize,
|
uint64_t flags, uint64_t entsize,
|
||||||
uint64_t addralign)
|
uint64_t addralign,
|
||||||
|
bool is_compressible_section)
|
||||||
{
|
{
|
||||||
bool is_string = (flags & elfcpp::SHF_STRINGS) != 0;
|
bool is_string = (flags & elfcpp::SHF_STRINGS) != 0;
|
||||||
|
|
||||||
@ -1227,30 +1248,56 @@ Output_section::add_merge_input_section(Relobj* object, unsigned int shndx,
|
|||||||
p != this->input_sections_.end();
|
p != this->input_sections_.end();
|
||||||
++p)
|
++p)
|
||||||
if (p->is_merge_section(is_string, entsize, addralign))
|
if (p->is_merge_section(is_string, entsize, addralign))
|
||||||
break;
|
{
|
||||||
|
p->add_input_section(object, shndx);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// We handle the actual constant merging in Output_merge_data or
|
// We handle the actual constant merging in Output_merge_data or
|
||||||
// Output_merge_string_data.
|
// Output_merge_string_data.
|
||||||
if (p != this->input_sections_.end())
|
Output_section_data* posd;
|
||||||
p->add_input_section(object, shndx);
|
if (!is_string)
|
||||||
|
posd = new Output_merge_data(entsize, addralign);
|
||||||
|
else if (is_compressible_section && options_.compress_debug_sections())
|
||||||
|
{
|
||||||
|
switch (entsize)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
posd = new Output_compressed_string<char>(addralign, this->options_);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
posd = new Output_compressed_string<uint16_t>(addralign,
|
||||||
|
this->options_);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
posd = new Output_compressed_string<uint32_t>(addralign,
|
||||||
|
this->options_);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Output_section_data* posd;
|
switch (entsize)
|
||||||
if (!is_string)
|
{
|
||||||
posd = new Output_merge_data(entsize, addralign);
|
case 1:
|
||||||
else if (entsize == 1)
|
posd = new Output_merge_string<char>(addralign);
|
||||||
posd = new Output_merge_string<char>(addralign);
|
break;
|
||||||
else if (entsize == 2)
|
case 2:
|
||||||
posd = new Output_merge_string<uint16_t>(addralign);
|
posd = new Output_merge_string<uint16_t>(addralign);
|
||||||
else if (entsize == 4)
|
break;
|
||||||
posd = new Output_merge_string<uint32_t>(addralign);
|
case 4:
|
||||||
else
|
posd = new Output_merge_string<uint32_t>(addralign);
|
||||||
return false;
|
break;
|
||||||
|
default:
|
||||||
this->add_output_merge_section(posd, is_string, entsize);
|
return false;
|
||||||
posd->add_input_section(object, shndx);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->add_output_merge_section(posd, is_string, entsize);
|
||||||
|
posd->add_input_section(object, shndx);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1367,6 +1414,29 @@ Output_section::set_final_data_size()
|
|||||||
this->set_data_size(off - startoff);
|
this->set_data_size(off - startoff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ask each output_section_data member if it wants to change the name
|
||||||
|
// of the output section. If any of them says yes, use this to set
|
||||||
|
// the new name. This should be called after all processing of this
|
||||||
|
// output section is done, but before the name is finally committed to
|
||||||
|
// the output-section's header.
|
||||||
|
|
||||||
|
bool
|
||||||
|
Output_section::maybe_modify_output_section_name()
|
||||||
|
{
|
||||||
|
for (Input_section_list::const_iterator it = input_sections_.begin();
|
||||||
|
it != input_sections_.end();
|
||||||
|
++it)
|
||||||
|
{
|
||||||
|
const char* newname = it->modified_output_section_name(this->name());
|
||||||
|
if (newname != NULL)
|
||||||
|
{
|
||||||
|
this->set_name(newname);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Write the section header to *OSHDR.
|
// Write the section header to *OSHDR.
|
||||||
|
|
||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
|
@ -432,6 +432,15 @@ class Output_section_data : public Output_data
|
|||||||
add_input_section(Relobj* object, unsigned int shndx)
|
add_input_section(Relobj* object, unsigned int shndx)
|
||||||
{ return this->do_add_input_section(object, shndx); }
|
{ return this->do_add_input_section(object, shndx); }
|
||||||
|
|
||||||
|
// This class may change the output section name. This is called
|
||||||
|
// right before shstrtab is written, so after all input-section
|
||||||
|
// layout processing is done. The input is the old name, and the
|
||||||
|
// output should be a new name (which will be copied into permanent
|
||||||
|
// storage) to change the name, or NULL to keep the name as-is.
|
||||||
|
virtual const char*
|
||||||
|
do_modified_output_section_name(const char*)
|
||||||
|
{ return NULL; }
|
||||||
|
|
||||||
// Given an input OBJECT, an input section index SHNDX within that
|
// Given an input OBJECT, an input section index SHNDX within that
|
||||||
// object, and an OFFSET relative to the start of that input
|
// object, and an OFFSET relative to the start of that input
|
||||||
// section, return whether or not the corresponding offset within
|
// section, return whether or not the corresponding offset within
|
||||||
@ -1308,7 +1317,8 @@ class Output_section : public Output_data
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Create an output section, giving the name, type, and flags.
|
// Create an output section, giving the name, type, and flags.
|
||||||
Output_section(const char* name, elfcpp::Elf_Word, elfcpp::Elf_Xword);
|
Output_section(const General_options& options,
|
||||||
|
const char* name, elfcpp::Elf_Word, elfcpp::Elf_Xword);
|
||||||
virtual ~Output_section();
|
virtual ~Output_section();
|
||||||
|
|
||||||
// Add a new input section SHNDX, named NAME, with header SHDR, from
|
// Add a new input section SHNDX, named NAME, with header SHDR, from
|
||||||
@ -1331,6 +1341,13 @@ class Output_section : public Output_data
|
|||||||
name() const
|
name() const
|
||||||
{ return this->name_; }
|
{ return this->name_; }
|
||||||
|
|
||||||
|
// Modify the section name. This should be called only after this
|
||||||
|
// section is done being constructed. The input should be a pointer
|
||||||
|
// into layout's namepool_.
|
||||||
|
void
|
||||||
|
set_name(const char* newname)
|
||||||
|
{ this->name_ = newname; }
|
||||||
|
|
||||||
// Return the section type.
|
// Return the section type.
|
||||||
elfcpp::Elf_Word
|
elfcpp::Elf_Word
|
||||||
type() const
|
type() const
|
||||||
@ -1518,6 +1535,16 @@ class Output_section : public Output_data
|
|||||||
write_header(const Layout*, const Stringpool*,
|
write_header(const Layout*, const Stringpool*,
|
||||||
elfcpp::Shdr_write<size, big_endian>*) const;
|
elfcpp::Shdr_write<size, big_endian>*) const;
|
||||||
|
|
||||||
|
// This class may change the output section name. This is called
|
||||||
|
// right before shstrtab is written, so after all input-section
|
||||||
|
// layout processing is done. This calls
|
||||||
|
// do_modified_output_section_name() on all its output_section_data
|
||||||
|
// members, and changes the name if any member so suggests. If
|
||||||
|
// several members would suggest, this takes the first, arbitrarily.
|
||||||
|
// Return true if the name was modified, false else.
|
||||||
|
bool
|
||||||
|
maybe_modify_output_section_name();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Return the section index in the output file.
|
// Return the section index in the output file.
|
||||||
unsigned int
|
unsigned int
|
||||||
@ -1663,6 +1690,15 @@ class Output_section : public Output_data
|
|||||||
void
|
void
|
||||||
set_address(uint64_t addr, off_t off, off_t secoff);
|
set_address(uint64_t addr, off_t off, off_t secoff);
|
||||||
|
|
||||||
|
// Call modified_output_section_name on the output-section-data object.
|
||||||
|
const char*
|
||||||
|
modified_output_section_name(const char* name) const
|
||||||
|
{
|
||||||
|
if (this->is_input_section())
|
||||||
|
return NULL;
|
||||||
|
return this->u2_.posd->do_modified_output_section_name(name);
|
||||||
|
}
|
||||||
|
|
||||||
// Add an input section, for SHF_MERGE sections.
|
// Add an input section, for SHF_MERGE sections.
|
||||||
bool
|
bool
|
||||||
add_input_section(Relobj* object, unsigned int shndx)
|
add_input_section(Relobj* object, unsigned int shndx)
|
||||||
@ -1777,7 +1813,8 @@ class Output_section : public Output_data
|
|||||||
// handled.
|
// handled.
|
||||||
bool
|
bool
|
||||||
add_merge_input_section(Relobj* object, unsigned int shndx, uint64_t flags,
|
add_merge_input_section(Relobj* object, unsigned int shndx, uint64_t flags,
|
||||||
uint64_t entsize, uint64_t addralign);
|
uint64_t entsize, uint64_t addralign,
|
||||||
|
bool can_compress_section);
|
||||||
|
|
||||||
// Add an output SHF_MERGE section POSD to this output section.
|
// Add an output SHF_MERGE section POSD to this output section.
|
||||||
// IS_STRING indicates whether it is a SHF_STRINGS section, and
|
// IS_STRING indicates whether it is a SHF_STRINGS section, and
|
||||||
@ -1789,8 +1826,10 @@ class Output_section : public Output_data
|
|||||||
|
|
||||||
// Most of these fields are only valid after layout.
|
// Most of these fields are only valid after layout.
|
||||||
|
|
||||||
|
// General options.
|
||||||
|
const General_options& options_;
|
||||||
// The name of the section. This will point into a Stringpool.
|
// The name of the section. This will point into a Stringpool.
|
||||||
const char* const name_;
|
const char* name_;
|
||||||
// The section address is in the parent class.
|
// The section address is in the parent class.
|
||||||
// The section alignment.
|
// The section alignment.
|
||||||
uint64_t addralign_;
|
uint64_t addralign_;
|
||||||
|
@ -2,6 +2,8 @@ archive.cc
|
|||||||
archive.h
|
archive.h
|
||||||
common.cc
|
common.cc
|
||||||
common.h
|
common.h
|
||||||
|
compressed_output.cc
|
||||||
|
compressed_output.h
|
||||||
defstd.cc
|
defstd.cc
|
||||||
defstd.h
|
defstd.h
|
||||||
dirsearch.cc
|
dirsearch.cc
|
||||||
|
296
gold/po/gold.pot
296
gold/po/gold.pot
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2007-11-20 16:37-0800\n"
|
"POT-Creation-Date: 2007-11-29 16:33-0800\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -61,6 +61,10 @@ msgstr ""
|
|||||||
msgid "%s: member at %zu is not an ELF object"
|
msgid "%s: member at %zu is not an ELF object"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: compressed_output.cc:140
|
||||||
|
msgid "Not compressing section data: zlib error"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: dirsearch.cc:68
|
#: dirsearch.cc:68
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: can not read directory: %s"
|
msgid "%s: can not read directory: %s"
|
||||||
@ -179,22 +183,22 @@ msgstr ""
|
|||||||
msgid "symbol %s has undefined version %s"
|
msgid "symbol %s has undefined version %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: errors.cc:77
|
#: errors.cc:88
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: warning: "
|
msgid "%s: warning: "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: errors.cc:112
|
#: errors.cc:127
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: warning: "
|
msgid "%s: %s: warning: "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: errors.cc:136
|
#: errors.cc:154
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: undefined reference to '%s'\n"
|
msgid "%s: %s: undefined reference to '%s'\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: errors.cc:146
|
#: errors.cc:164
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: "
|
msgid "%s: "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -271,62 +275,62 @@ msgstr ""
|
|||||||
msgid "cannot mix -static with dynamic object %s"
|
msgid "cannot mix -static with dynamic object %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: gold-threads.cc:69
|
#: gold-threads.cc:102
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "pthead_mutextattr_init failed: %s"
|
msgid "pthead_mutextattr_init failed: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: gold-threads.cc:73
|
#: gold-threads.cc:106
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "pthread_mutextattr_settype failed: %s"
|
msgid "pthread_mutextattr_settype failed: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: gold-threads.cc:78
|
#: gold-threads.cc:111
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "pthread_mutex_init failed: %s"
|
msgid "pthread_mutex_init failed: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: gold-threads.cc:82
|
#: gold-threads.cc:115
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "pthread_mutexattr_destroy failed: %s"
|
msgid "pthread_mutexattr_destroy failed: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: gold-threads.cc:89
|
#: gold-threads.cc:122
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "pthread_mutex_destroy failed: %s"
|
msgid "pthread_mutex_destroy failed: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: gold-threads.cc:97
|
#: gold-threads.cc:130
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "pthread_mutex_lock failed: %s"
|
msgid "pthread_mutex_lock failed: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: gold-threads.cc:105
|
#: gold-threads.cc:138
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "pthread_mutex_unlock failed: %s"
|
msgid "pthread_mutex_unlock failed: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: gold-threads.cc:193
|
#: gold-threads.cc:219
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "pthread_cond_init failed: %s"
|
msgid "pthread_cond_init failed: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: gold-threads.cc:200
|
#: gold-threads.cc:226
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "pthread_cond_destroy failed: %s"
|
msgid "pthread_cond_destroy failed: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: gold-threads.cc:208
|
#: gold-threads.cc:235
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "pthread_cond_wait failed: %s"
|
msgid "pthread_cond_wait failed: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: gold-threads.cc:216
|
#: gold-threads.cc:243
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "pthread_cond_signal failed: %s"
|
msgid "pthread_cond_signal failed: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: gold-threads.cc:224
|
#: gold-threads.cc:251
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "pthread_cond_broadcast failed: %s"
|
msgid "pthread_cond_broadcast failed: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -371,11 +375,11 @@ msgstr ""
|
|||||||
msgid "both SUN and GNU model TLS relocations"
|
msgid "both SUN and GNU model TLS relocations"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: merge.cc:283
|
#: merge.cc:464
|
||||||
msgid "mergeable string section length not multiple of character size"
|
msgid "mergeable string section length not multiple of character size"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: merge.cc:299
|
#: merge.cc:480
|
||||||
msgid "entry in mergeable string section not null terminated"
|
msgid "entry in mergeable string section not null terminated"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -419,7 +423,7 @@ msgstr ""
|
|||||||
msgid "section %u in section group %u out of range"
|
msgid "section %u in section group %u out of range"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:534 reloc.cc:226 reloc.cc:493
|
#: object.cc:534 reloc.cc:229 reloc.cc:496
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "relocation section %u has bad info %u"
|
msgid "relocation section %u has bad info %u"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -549,314 +553,331 @@ msgstr ""
|
|||||||
msgid "Bind defined symbols locally"
|
msgid "Bind defined symbols locally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:379
|
|
||||||
msgid "Demangle C++ symbols in log messages"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: options.cc:382
|
|
||||||
msgid "Do not demangle C++ symbols in log messages"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: options.cc:385
|
#: options.cc:385
|
||||||
msgid "Try to detect violations of the One Definition Rule"
|
msgid "Compress .debug_* sections in the output file (default is none)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:387
|
#: options.cc:387
|
||||||
msgid "Export all dynamic symbols"
|
msgid "--compress-debug-sections=[none"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:389
|
#: options.cc:387
|
||||||
msgid "Create exception frame header"
|
msgid "]"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:391
|
#: options.cc:390
|
||||||
msgid "Set dynamic linker path"
|
msgid "Demangle C++ symbols in log messages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:392
|
#: options.cc:393
|
||||||
msgid "-I PROGRAM, --dynamic-linker PROGRAM"
|
msgid "Do not demangle C++ symbols in log messages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:394
|
#: options.cc:396
|
||||||
msgid "Search for library LIBNAME"
|
msgid "Try to detect violations of the One Definition Rule"
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: options.cc:395
|
|
||||||
msgid "-lLIBNAME, --library LIBNAME"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: options.cc:397
|
|
||||||
msgid "Add directory to search path"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:398
|
#: options.cc:398
|
||||||
msgid "-L DIR, --library-path DIR"
|
msgid "Export all dynamic symbols"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:400
|
#: options.cc:400
|
||||||
msgid "Ignored for compatibility"
|
msgid "Create exception frame header"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:402
|
#: options.cc:402
|
||||||
msgid "Set output file name"
|
msgid "Set dynamic linker path"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:403
|
#: options.cc:403
|
||||||
msgid "-o FILE, --output FILE"
|
msgid "-I PROGRAM, --dynamic-linker PROGRAM"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:405
|
#: options.cc:405
|
||||||
msgid "Optimize output file size"
|
msgid "Search for library LIBNAME"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:406
|
#: options.cc:406
|
||||||
msgid "-O level"
|
msgid "-lLIBNAME, --library LIBNAME"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:408
|
#: options.cc:408
|
||||||
msgid "Generate relocatable output"
|
msgid "Add directory to search path"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:410
|
#: options.cc:409
|
||||||
msgid "Add DIR to runtime search path"
|
msgid "-L DIR, --library-path DIR"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:411
|
#: options.cc:411
|
||||||
msgid "-R DIR, -rpath DIR"
|
msgid "Ignored for compatibility"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: options.cc:413
|
||||||
|
msgid "Set output file name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:414
|
#: options.cc:414
|
||||||
msgid "Add DIR to link time shared library search path"
|
msgid "-o FILE, --output FILE"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:415
|
#: options.cc:416
|
||||||
msgid "--rpath-link DIR"
|
msgid "Optimize output file size"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:417
|
#: options.cc:417
|
||||||
|
msgid "-O level"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: options.cc:419
|
||||||
|
msgid "Generate relocatable output"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: options.cc:421
|
||||||
|
msgid "Add DIR to runtime search path"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: options.cc:422
|
||||||
|
msgid "-R DIR, -rpath DIR"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: options.cc:425
|
||||||
|
msgid "Add DIR to link time shared library search path"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: options.cc:426
|
||||||
|
msgid "--rpath-link DIR"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: options.cc:428
|
||||||
msgid "Strip all symbols"
|
msgid "Strip all symbols"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:420
|
#: options.cc:431
|
||||||
msgid "Strip debug symbols that are unused by gdb (at least versions <= 6.7)"
|
msgid "Strip debug symbols that are unused by gdb (at least versions <= 6.7)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. This must come after -Sdebug since it's a prefix of it.
|
#. This must come after -Sdebug since it's a prefix of it.
|
||||||
#: options.cc:424
|
#: options.cc:435
|
||||||
msgid "Strip debugging information"
|
msgid "Strip debugging information"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:426
|
#: options.cc:437
|
||||||
msgid "Generate shared library"
|
msgid "Generate shared library"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:428
|
#: options.cc:439
|
||||||
msgid "Do not link against shared libraries"
|
msgid "Do not link against shared libraries"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:430
|
#: options.cc:441
|
||||||
msgid "Print resource usage statistics"
|
msgid "Print resource usage statistics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:432
|
#: options.cc:443
|
||||||
msgid "Set target system root directory"
|
msgid "Set target system root directory"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:433
|
#: options.cc:444
|
||||||
msgid "--sysroot DIR"
|
msgid "--sysroot DIR"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:434
|
#: options.cc:445
|
||||||
msgid "Set the address of the .text section"
|
msgid "Set the address of the .text section"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:435
|
#: options.cc:446
|
||||||
msgid "-Ttext ADDRESS"
|
msgid "-Ttext ADDRESS"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. This must come after -Ttext since it's a prefix of it.
|
#. This must come after -Ttext since it's a prefix of it.
|
||||||
#: options.cc:438
|
#: options.cc:449
|
||||||
msgid "Read linker script"
|
msgid "Read linker script"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:439
|
#: options.cc:450
|
||||||
msgid "-T FILE, --script FILE"
|
msgid "-T FILE, --script FILE"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:441
|
#: options.cc:452
|
||||||
msgid "Run the linker multi-threaded"
|
msgid "Run the linker multi-threaded"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:443
|
#: options.cc:454
|
||||||
msgid "Do not run the linker multi-threaded"
|
msgid "Do not run the linker multi-threaded"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:445
|
#: options.cc:456
|
||||||
msgid "Number of threads to use"
|
msgid "Number of threads to use"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:446
|
#: options.cc:457
|
||||||
msgid "--thread-count COUNT"
|
msgid "--thread-count COUNT"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:449
|
#: options.cc:460
|
||||||
msgid "Number of threads to use in initial pass"
|
msgid "Number of threads to use in initial pass"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:450
|
#: options.cc:461
|
||||||
msgid "--thread-count-initial COUNT"
|
msgid "--thread-count-initial COUNT"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:453
|
#: options.cc:464
|
||||||
msgid "Number of threads to use in middle pass"
|
msgid "Number of threads to use in middle pass"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:454
|
#: options.cc:465
|
||||||
msgid "--thread-count-middle COUNT"
|
msgid "--thread-count-middle COUNT"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:457
|
#: options.cc:468
|
||||||
msgid "Number of threads to use in final pass"
|
msgid "Number of threads to use in final pass"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:458
|
#: options.cc:469
|
||||||
msgid "--thread-count-final COUNT"
|
msgid "--thread-count-final COUNT"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:461
|
#: options.cc:472
|
||||||
msgid "Include all archive contents"
|
msgid "Include all archive contents"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:465
|
#: options.cc:476
|
||||||
msgid "Include only needed archive contents"
|
msgid "Include only needed archive contents"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:470
|
#: options.cc:481
|
||||||
msgid ""
|
msgid ""
|
||||||
"Subcommands as follows:\n"
|
"Subcommands as follows:\n"
|
||||||
" -z execstack Mark output as requiring executable stack\n"
|
" -z execstack Mark output as requiring executable stack\n"
|
||||||
" -z noexecstack Mark output as not requiring executable stack"
|
" -z noexecstack Mark output as not requiring executable stack"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:473
|
#: options.cc:484
|
||||||
msgid "-z SUBCOMMAND"
|
msgid "-z SUBCOMMAND"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:476
|
#: options.cc:487
|
||||||
msgid "Start a library search group"
|
msgid "Start a library search group"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:478
|
#: options.cc:489
|
||||||
msgid "End a library search group"
|
msgid "End a library search group"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:480
|
#: options.cc:491
|
||||||
msgid "Report usage information"
|
msgid "Report usage information"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:482
|
#: options.cc:493
|
||||||
msgid "Report version information"
|
msgid "Report version information"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:484
|
#: options.cc:495
|
||||||
msgid "Turn on debugging (all,task)"
|
msgid "Turn on debugging (all,task)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:485
|
#: options.cc:496
|
||||||
msgid "--debug=TYPE"
|
msgid "--debug=TYPE"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:578
|
#: options.cc:590
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: unrecognized -z subcommand: %s\n"
|
msgid "%s: unrecognized -z subcommand: %s\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:601
|
#: options.cc:613
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: unrecognized --debug subcommand: %s\n"
|
msgid "%s: unrecognized --debug subcommand: %s\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:781
|
#: options.cc:793
|
||||||
msgid "unexpected argument"
|
msgid "unexpected argument"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:788 options.cc:840 options.cc:921
|
#: options.cc:800 options.cc:852 options.cc:933
|
||||||
msgid "missing argument"
|
msgid "missing argument"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:801 options.cc:849
|
#: options.cc:813 options.cc:861
|
||||||
msgid "unknown option"
|
msgid "unknown option"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:867
|
#: options.cc:879
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: missing group end\n"
|
msgid "%s: missing group end\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:995
|
#: options.cc:1007
|
||||||
msgid "may not nest groups"
|
msgid "may not nest groups"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:1005
|
#: options.cc:1017
|
||||||
msgid "group end without group start"
|
msgid "group end without group start"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:1015
|
#: options.cc:1027
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: use the --help option for usage information\n"
|
msgid "%s: use the --help option for usage information\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:1024
|
#: options.cc:1036
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: %s\n"
|
msgid "%s: %s: %s\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.cc:1033
|
#: options.cc:1045
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: -%c: %s\n"
|
msgid "%s: -%c: %s\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.h:393
|
#: options.h:372
|
||||||
|
#, c-format
|
||||||
|
msgid "Unsupported argument to --compress-debug-symbols: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: options.h:424
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: invalid argument to -Ttext: %s\n"
|
msgid "%s: invalid argument to -Ttext: %s\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: options.h:406
|
#: options.h:437
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: invalid thread count: %s\n"
|
msgid "%s: invalid thread count: %s\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: output.cc:1108
|
#: output.cc:1122
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "invalid alignment %lu for section \"%s\""
|
msgid "invalid alignment %lu for section \"%s\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: output.cc:1870
|
#: output.cc:1941
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: open: %s"
|
msgid "%s: open: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: output.cc:1875
|
#: output.cc:1953 output.cc:1986
|
||||||
#, c-format
|
|
||||||
msgid "%s: lseek: %s"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: output.cc:1878
|
|
||||||
#, c-format
|
|
||||||
msgid "%s: write: %s"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: output.cc:1884
|
|
||||||
#, c-format
|
|
||||||
msgid "%s: mmap: %s"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: output.cc:1894
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: munmap: %s"
|
msgid "%s: munmap: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: output.cc:1898
|
#: output.cc:1967
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: lseek: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: output.cc:1970
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: write: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: output.cc:1976
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: mmap: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: output.cc:1990
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: close: %s"
|
msgid "%s: close: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -877,22 +898,22 @@ msgstr ""
|
|||||||
msgid "%s: not an object or archive"
|
msgid "%s: not an object or archive"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: reloc.cc:245 reloc.cc:511
|
#: reloc.cc:248 reloc.cc:514
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "relocation section %u uses unexpected symbol table %u"
|
msgid "relocation section %u uses unexpected symbol table %u"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: reloc.cc:260 reloc.cc:529
|
#: reloc.cc:263 reloc.cc:532
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "unexpected entsize for reloc section %u: %lu != %u"
|
msgid "unexpected entsize for reloc section %u: %lu != %u"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: reloc.cc:269 reloc.cc:538
|
#: reloc.cc:272 reloc.cc:541
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "reloc section %u size %lu uneven"
|
msgid "reloc section %u size %lu uneven"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: reloc.cc:729
|
#: reloc.cc:732
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "reloc section size %zu is not a multiple of reloc size %d\n"
|
msgid "reloc section size %zu is not a multiple of reloc size %d\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -934,41 +955,41 @@ msgid ""
|
|||||||
"T"
|
"T"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: symtab.cc:576
|
#: symtab.cc:597
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "bad global symbol name offset %u at %zu"
|
msgid "bad global symbol name offset %u at %zu"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: symtab.cc:654
|
#: symtab.cc:675
|
||||||
msgid "too few symbol versions"
|
msgid "too few symbol versions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: symtab.cc:683
|
#: symtab.cc:704
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "bad symbol name offset %u at %zu"
|
msgid "bad symbol name offset %u at %zu"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: symtab.cc:737
|
#: symtab.cc:758
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "versym for symbol %zu out of range: %u"
|
msgid "versym for symbol %zu out of range: %u"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: symtab.cc:745
|
#: symtab.cc:766
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "versym for symbol %zu has no name: %u"
|
msgid "versym for symbol %zu has no name: %u"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: symtab.cc:1463 symtab.cc:1676
|
#: symtab.cc:1484 symtab.cc:1697
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: unsupported symbol section 0x%x"
|
msgid "%s: unsupported symbol section 0x%x"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: symtab.cc:1800
|
#: symtab.cc:1821
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: undefined reference to '%s'"
|
msgid "%s: undefined reference to '%s'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: symtab.cc:1941
|
#: symtab.cc:1962
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"while linking %s: symbol '%s' defined in multiple places (possible ODR "
|
"while linking %s: symbol '%s' defined in multiple places (possible ODR "
|
||||||
@ -1003,7 +1024,12 @@ msgid ""
|
|||||||
"This program has absolutely no warranty.\n"
|
"This program has absolutely no warranty.\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: workqueue-threads.cc:106
|
#: workqueue.cc:484
|
||||||
|
#, c-format
|
||||||
|
msgid "gold task queue:\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: workqueue-threads.cc:107
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s failed: %s"
|
msgid "%s failed: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -41,12 +41,21 @@ Stringpool_template<Stringpool_char>::Stringpool_template()
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Stringpool_char>
|
template<typename Stringpool_char>
|
||||||
Stringpool_template<Stringpool_char>::~Stringpool_template()
|
void
|
||||||
|
Stringpool_template<Stringpool_char>::clear()
|
||||||
{
|
{
|
||||||
for (typename std::list<Stringdata*>::iterator p = this->strings_.begin();
|
for (typename std::list<Stringdata*>::iterator p = this->strings_.begin();
|
||||||
p != this->strings_.end();
|
p != this->strings_.end();
|
||||||
++p)
|
++p)
|
||||||
delete[] reinterpret_cast<char*>(*p);
|
delete[] reinterpret_cast<char*>(*p);
|
||||||
|
this->strings_.clear();
|
||||||
|
this->string_set_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stringpool_char>
|
||||||
|
Stringpool_template<Stringpool_char>::~Stringpool_template()
|
||||||
|
{
|
||||||
|
this->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the length of a string of arbitrary character type.
|
// Return the length of a string of arbitrary character type.
|
||||||
@ -413,6 +422,28 @@ Stringpool_template<Stringpool_char>::get_offset(const Stringpool_char* s)
|
|||||||
gold_unreachable();
|
gold_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write the ELF strtab into the buffer.
|
||||||
|
|
||||||
|
template<typename Stringpool_char>
|
||||||
|
void
|
||||||
|
Stringpool_template<Stringpool_char>::write_to_buffer(char* buffer,
|
||||||
|
size_t bufsize)
|
||||||
|
{
|
||||||
|
gold_assert(this->strtab_size_ != 0);
|
||||||
|
if (bufsize < this->strtab_size_) // Quiet the compiler in opt mode.
|
||||||
|
gold_assert(bufsize >= this->strtab_size_);
|
||||||
|
if (this->zero_null_)
|
||||||
|
buffer[0] = '\0';
|
||||||
|
for (typename String_set_type::const_iterator p = this->string_set_.begin();
|
||||||
|
p != this->string_set_.end();
|
||||||
|
++p)
|
||||||
|
{
|
||||||
|
const int len = (string_length(p->first) + 1) * sizeof(Stringpool_char);
|
||||||
|
gold_assert(p->second.second + len <= this->strtab_size_);
|
||||||
|
memcpy(buffer + p->second.second, p->first, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Write the ELF strtab into the output file at the specified offset.
|
// Write the ELF strtab into the output file at the specified offset.
|
||||||
|
|
||||||
template<typename Stringpool_char>
|
template<typename Stringpool_char>
|
||||||
@ -420,16 +451,9 @@ void
|
|||||||
Stringpool_template<Stringpool_char>::write(Output_file* of, off_t offset)
|
Stringpool_template<Stringpool_char>::write(Output_file* of, off_t offset)
|
||||||
{
|
{
|
||||||
gold_assert(this->strtab_size_ != 0);
|
gold_assert(this->strtab_size_ != 0);
|
||||||
unsigned char* viewu = of->get_output_view(offset, this->strtab_size_);
|
unsigned char* view = of->get_output_view(offset, this->strtab_size_);
|
||||||
char* view = reinterpret_cast<char*>(viewu);
|
this->write_to_buffer(reinterpret_cast<char*>(view), this->strtab_size_);
|
||||||
if (this->zero_null_)
|
of->write_output_view(offset, this->strtab_size_, view);
|
||||||
view[0] = '\0';
|
|
||||||
for (typename String_set_type::const_iterator p = this->string_set_.begin();
|
|
||||||
p != this->string_set_.end();
|
|
||||||
++p)
|
|
||||||
memcpy(view + p->second.second, p->first,
|
|
||||||
(string_length(p->first) + 1) * sizeof(Stringpool_char));
|
|
||||||
of->write_output_view(offset, this->strtab_size_, viewu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instantiate the templates we need.
|
// Instantiate the templates we need.
|
||||||
|
@ -84,6 +84,10 @@ class Stringpool_template
|
|||||||
|
|
||||||
~Stringpool_template();
|
~Stringpool_template();
|
||||||
|
|
||||||
|
// Clear all the data from the stringpool.
|
||||||
|
void
|
||||||
|
clear();
|
||||||
|
|
||||||
// Indicate that we should not reserve offset 0 to hold the empty
|
// Indicate that we should not reserve offset 0 to hold the empty
|
||||||
// string when converting the stringpool to a string table. This
|
// string when converting the stringpool to a string table. This
|
||||||
// should not be called for a proper ELF SHT_STRTAB section.
|
// should not be called for a proper ELF SHT_STRTAB section.
|
||||||
@ -139,6 +143,12 @@ class Stringpool_template
|
|||||||
void
|
void
|
||||||
write(Output_file*, off_t offset);
|
write(Output_file*, off_t offset);
|
||||||
|
|
||||||
|
// Write the string table into the specified buffer, of the
|
||||||
|
// specified size. buffer_size should be at least
|
||||||
|
// get_strtab_size().
|
||||||
|
void
|
||||||
|
write_to_buffer(char* buffer, size_t buffer_size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Stringpool_template(const Stringpool_template&);
|
Stringpool_template(const Stringpool_template&);
|
||||||
Stringpool_template& operator=(const Stringpool_template&);
|
Stringpool_template& operator=(const Stringpool_template&);
|
||||||
|
@ -445,6 +445,7 @@ CATOBJEXT = @CATOBJEXT@
|
|||||||
CC = @CC@
|
CC = @CC@
|
||||||
CCDEPMODE = @CCDEPMODE@
|
CCDEPMODE = @CCDEPMODE@
|
||||||
CFLAGS = @CFLAGS@
|
CFLAGS = @CFLAGS@
|
||||||
|
CPP = @CPP@
|
||||||
CPPFLAGS = @CPPFLAGS@
|
CPPFLAGS = @CPPFLAGS@
|
||||||
CXX = @CXX@
|
CXX = @CXX@
|
||||||
CXXCPP = @CXXCPP@
|
CXXCPP = @CXXCPP@
|
||||||
|
Loading…
Reference in New Issue
Block a user