#include "compressed_output.h"
#include "reduced_debug_output.h"
#include "reloc.h"
+#include "descriptors.h"
#include "layout.h"
+#include "plugin.h"
namespace gold
{
Layout::include_section(Sized_relobj<size, big_endian>*, const char* name,
const elfcpp::Shdr<size, big_endian>& shdr)
{
+ if (shdr.get_sh_flags() & elfcpp::SHF_EXCLUDE)
+ return false;
+
switch (shdr.get_sh_type())
{
case elfcpp::SHT_NULL:
&& !is_gdb_debug_section(name))
return false;
}
+ if (parameters->options().strip_lto_sections()
+ && !parameters->options().relocatable()
+ && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0)
+ {
+ // Ignore LTO sections containing intermediate code.
+ if (is_prefix_of(".gnu.lto_", name))
+ return false;
+ }
return true;
default:
if ((flags & elfcpp::SHF_TLS) != 0)
{
if (this->tls_segment_ == NULL)
- this->tls_segment_ = this->make_output_segment(elfcpp::PT_TLS,
- seg_flags);
+ this->make_output_segment(elfcpp::PT_TLS, seg_flags);
this->tls_segment_->add_output_section(os, seg_flags);
}
{
gold_assert(seg_flags == (elfcpp::PF_R | elfcpp::PF_W));
if (this->relro_segment_ == NULL)
- this->relro_segment_ = this->make_output_segment(elfcpp::PT_GNU_RELRO,
- seg_flags);
+ this->make_output_segment(elfcpp::PT_GNU_RELRO, seg_flags);
this->relro_segment_->add_output_section(os, seg_flags);
}
}
char buffer[uuidsz];
memset(buffer, 0, uuidsz);
- int descriptor = ::open("/dev/urandom", O_RDONLY);
+ int descriptor = open_descriptor(-1, "/dev/urandom", O_RDONLY);
if (descriptor < 0)
gold_error(_("--build-id=uuid failed: could not open /dev/urandom: %s"),
strerror(errno));
else
{
ssize_t got = ::read(descriptor, buffer, uuidsz);
- ::close(descriptor);
+ release_descriptor(descriptor, true);
if (got < 0)
gold_error(_("/dev/urandom: read failed: %s"), strerror(errno));
else if (static_cast<size_t>(got) != uuidsz)
}
}
+ const bool check_sections = parameters->options().check_sections();
+ Output_segment* last_load_segment = NULL;
+
bool was_readonly = false;
for (Segment_list::iterator p = this->segment_list_.begin();
p != this->segment_list_.end();
if (((*p)->flags() & elfcpp::PF_W) == 0)
was_readonly = true;
+
+ // Implement --check-sections. We know that the segments
+ // are sorted by LMA.
+ if (check_sections && last_load_segment != NULL)
+ {
+ gold_assert(last_load_segment->paddr() <= (*p)->paddr());
+ if (last_load_segment->paddr() + last_load_segment->memsz()
+ > (*p)->paddr())
+ {
+ unsigned long long lb1 = last_load_segment->paddr();
+ unsigned long long le1 = lb1 + last_load_segment->memsz();
+ unsigned long long lb2 = (*p)->paddr();
+ unsigned long long le2 = lb2 + (*p)->memsz();
+ gold_error(_("load segment overlap [0x%llx -> 0x%llx] and "
+ "[0x%llx -> 0x%llx]"),
+ lb1, le1, lb2, le2);
+ }
+ }
+ last_load_segment = *p;
}
}
}
if (parameters->options().shared() && this->has_static_tls())
flags |= elfcpp::DF_STATIC_TLS;
+ if (parameters->options().origin())
+ flags |= elfcpp::DF_ORIGIN;
odyn->add_constant(elfcpp::DT_FLAGS, flags);
flags = 0;
flags &= ~(elfcpp::DF_1_INITFIRST
| elfcpp::DF_1_NODELETE
| elfcpp::DF_1_NOOPEN);
+ if (parameters->options().origin())
+ flags |= elfcpp::DF_1_ORIGIN;
if (flags)
odyn->add_constant(elfcpp::DT_FLAGS_1, flags);
}
if (ins.first->second.group_)
{
// We've already seen a real section group with this signature.
+ // If the kept group is from a plugin object, and we're in
+ // the replacement phase, accept the new one as a replacement.
+ if (ins.first->second.object_ == NULL
+ && parameters->options().plugins()->in_replacement_phase())
+ {
+ ins.first->second = kept;
+ return true;
+ }
return false;
}
else if (group)
gold_assert(!parameters->options().relocatable());
Output_segment* oseg = new Output_segment(type, flags);
this->segment_list_.push_back(oseg);
+
+ if (type == elfcpp::PT_TLS)
+ this->tls_segment_ = oseg;
+ else if (type == elfcpp::PT_GNU_RELRO)
+ this->relro_segment_ = oseg;
+
return oseg;
}