int TransportRegistry::load_transport_configuration(const OPENDDS_STRING& file_name, ACE_Configuration_Heap& cf) { const ACE_Configuration_Section_Key &root = cf.root_section(); // Create a vector to hold configuration information so we can populate // them after the transports instances are created. typedef std::pair<TransportConfig_rch, OPENDDS_VECTOR(OPENDDS_STRING) > ConfigInfo; OPENDDS_VECTOR(ConfigInfo) configInfoVec; // Record the transport instances created, so we can place them // in the implicit transport configuration for this file. OPENDDS_LIST(TransportInst_rch) instances; ACE_TString sect_name; for (int index = 0; cf.enumerate_sections(root, index, sect_name) == 0; ++index) { if (ACE_OS::strcmp(sect_name.c_str(), TRANSPORT_SECTION_NAME) == 0) { // found the [transport/*] section, now iterate through subsections... ACE_Configuration_Section_Key sect; if (cf.open_section(root, sect_name.c_str(), 0, sect) != 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("failed to open section %s\n"), sect_name.c_str()), -1); } else { // Ensure there are no properties in this section ValueMap vm; if (pullValues(cf, sect, vm) > 0) { // There are values inside [transport] ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("transport sections must have a section name\n"), sect_name.c_str()), -1); } // Process the subsections of this section (the individual transport // impls). KeyList keys; if (processSections( cf, sect, keys ) != 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("too many nesting layers in [%s] section.\n"), sect_name.c_str()), -1); } for (KeyList::const_iterator it=keys.begin(); it != keys.end(); ++it) { OPENDDS_STRING transport_id = (*it).first; ACE_Configuration_Section_Key inst_sect = (*it).second; ValueMap values; if (pullValues( cf, (*it).second, values ) != 0) { // Get the factory_id for the transport. OPENDDS_STRING transport_type; ValueMap::const_iterator vm_it = values.find("transport_type"); if (vm_it != values.end()) { transport_type = (*vm_it).second; } else { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("missing transport_type in [transport/%C] section.\n"), transport_id.c_str()), -1); } // Create the TransportInst object and load the transport // configuration in ACE_Configuration_Heap to the TransportInst // object. TransportInst_rch inst = this->create_inst(transport_id, transport_type); if (inst == 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("Unable to create transport instance in [transport/%C] section.\n"), transport_id.c_str()), -1); } instances.push_back(inst); inst->load(cf, inst_sect); } else { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("missing transport_type in [transport/%C] section.\n"), transport_id.c_str()), -1); } } } } else if (ACE_OS::strcmp(sect_name.c_str(), CONFIG_SECTION_NAME) == 0) { // found the [config/*] section, now iterate through subsections... ACE_Configuration_Section_Key sect; if (cf.open_section(root, sect_name.c_str(), 0, sect) != 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("failed to open section [%s]\n"), sect_name.c_str()), -1); } else { // Ensure there are no properties in this section ValueMap vm; if (pullValues(cf, sect, vm) > 0) { // There are values inside [config] ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("config sections must have a section name\n"), sect_name.c_str()), -1); } // Process the subsections of this section (the individual config // impls). KeyList keys; if (processSections( cf, sect, keys ) != 0) { // Don't allow multiple layers of nesting ([config/x/y]). ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("too many nesting layers in [%s] section.\n"), sect_name.c_str()), -1); } for (KeyList::const_iterator it=keys.begin(); it != keys.end(); ++it) { OPENDDS_STRING config_id = (*it).first; // Create a TransportConfig object. TransportConfig_rch config = this->create_config(config_id); if (config == 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("Unable to create transport config in [config/%C] section.\n"), config_id.c_str()), -1); } ValueMap values; pullValues( cf, (*it).second, values ); ConfigInfo configInfo; configInfo.first = config; for (ValueMap::const_iterator it=values.begin(); it != values.end(); ++it) { OPENDDS_STRING name = (*it).first; if (name == "transports") { OPENDDS_STRING value = (*it).second; char delim = ','; size_t pos = 0; OPENDDS_STRING token; while ((pos = value.find(delim)) != OPENDDS_STRING::npos) { token = value.substr(0, pos); configInfo.second.push_back(token); value.erase(0, pos + 1); } configInfo.second.push_back(value); configInfoVec.push_back(configInfo); } else if (name == "swap_bytes") { OPENDDS_STRING value = (*it).second; if ((value == "1") || (value == "true")) { config->swap_bytes_ = true; } else if ((value != "0") && (value != "false")) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("Illegal value for swap_bytes (%C) in [config/%C] section.\n"), value.c_str(), config_id.c_str()), -1); } } else if (name == "passive_connect_duration") { OPENDDS_STRING value = (*it).second; if (!convertToInteger(value, config->passive_connect_duration_)) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("Illegal integer value for passive_connect_duration (%s) in [config/%C] section.\n"), value.c_str(), config_id.c_str()), -1); } } else { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("Unexpected entry (%C) in [config/%C] section.\n"), name.c_str(), config_id.c_str()), -1); } } if (configInfo.second.size() == 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("No transport instances listed in [config/%C] section.\n"), config_id.c_str()), -1); } } } } else if (ACE_OS::strncmp(sect_name.c_str(), OLD_TRANSPORT_PREFIX.c_str(), OLD_TRANSPORT_PREFIX.length()) == 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: ") ACE_TEXT("Obsolete transport configuration found (%s).\n"), sect_name.c_str()), -1); } } // Populate the configurations with instances for (unsigned int i = 0; i < configInfoVec.size(); ++i) { TransportConfig_rch config = configInfoVec[i].first; OPENDDS_VECTOR(OPENDDS_STRING)& insts = configInfoVec[i].second; for (unsigned int j = 0; j < insts.size(); ++j) { TransportInst_rch inst = this->get_inst(insts[j]); if (inst == 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("The inst (%C) in [config/%C] section is undefined.\n"), insts[j].c_str(), config->name().c_str()), -1); } config->instances_.push_back(inst); } } // Create and populate the default configuration for this // file with all the instances from this file. if (!instances.empty()) { TransportConfig_rch config = this->create_config(file_name); if (config == 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("Unable to create default transport config.\n"), file_name.c_str()), -1); } instances.sort(predicate); for (OPENDDS_LIST(TransportInst_rch)::const_iterator it = instances.begin(); it != instances.end(); ++it) { config->instances_.push_back(*it); } } return 0; }
bool Loader::loadRPL(UserModule &module, const char *buffer, size_t size) { auto in = BigEndianView { buffer, size }; auto header = elf::Header { }; auto info = elf::FileInfo { }; auto sections = std::vector<elf::Section> { }; // Read header if (!elf::readHeader(in, header)) { gLog->error("Failed elf::readHeader"); return false; } // Check it is a CAFE abi rpl if (header.abi != elf::EABI_CAFE) { gLog->error("Unexpected elf abi found {:02x} expected {:02x}", header.abi, elf::EABI_CAFE); return false; } // Read sections if (!elf::readSections(in, header, sections)) { gLog->error("Failed elf::readSections"); return false; } // Process sections, find our data and code sections processSections(module, sections, sections[header.shstrndx].data.data()); // Update EntryInfo loadFileInfo(info, sections); module.entryPoint = header.entry; module.defaultStackSize = info.stackSize; // Allocate code & data sections in memory auto codeStart = module.codeAddressRange.first; auto codeSize = module.maxCodeSize; gMemory.alloc(codeStart, codeSize); // TODO: Append code to end of other loaded code sections auto dataStart = alignUp(codeStart + codeSize, 4096); auto dataSize = alignUp(module.dataAddressRange.second - module.dataAddressRange.first, 4096); auto dataEnd = dataStart + dataSize; gMemory.alloc(dataStart, dataSize); // TODO: Use OSDynLoad_MemAlloc for data section allocation // Update MEM2 memory bounds be_val<uint32_t> mem2start, mem2size; OSGetMemBound(OSMemoryType::MEM2, &mem2start, &mem2size); OSSetMemBound(OSMemoryType::MEM2, dataEnd, mem2size - (dataEnd - mem2start)); // Relocate sections relocateSections(sections, module.codeAddressRange.first, codeStart, module.dataAddressRange.first, dataStart); module.codeAddressRange.first = codeStart; module.codeAddressRange.second = codeStart + codeSize; module.dataAddressRange.first = dataStart; module.dataAddressRange.second = dataStart + dataSize; // Relocate entry point for (auto i = 0u; i < sections.size(); ++i) { auto §ion = sections[i]; if (section.header.addr <= header.entry && section.header.addr + section.data.size() > header.entry) { auto offset = section.section->address - section.header.addr; module.entryPoint = header.entry + offset; break; } } // Load sections into memory loadSections(sections); // Process small data sections processSmallDataSections(module); // Process symbols // TODO: Support more than one symbol section? for (auto i = 0u; i < sections.size(); ++i) { auto §ion = sections[i]; if (section.header.type != elf::SHT_SYMTAB) { continue; } processSymbols(module, section, sections); } // Process relocations for (auto i = 0u; i < sections.size(); ++i) { auto §ion = sections[i]; if (section.header.type != elf::SHT_RELA) { continue; } processRelocations(module, section, sections); } if (0) { // Print address ranges gLog->debug("Loaded module!"); gLog->debug("Code {:08x} -> {:08x}", module.codeAddressRange.first, module.codeAddressRange.second); gLog->debug("Data {:08x} -> {:08x}", module.dataAddressRange.first, module.dataAddressRange.second); // Print all sections gLog->debug("Sections:"); for (auto i = 0u; i < module.sections.size(); ++i) { auto section = module.sections[i]; gLog->debug("{:08x} {} {:x}", section->address, section->name, section->size); } // Print all symbols gLog->debug("Symbols:"); for (auto i = 0u; i < module.symbols.size(); ++i) { auto symbol = module.symbols[i]; if (symbol && symbol->name.size()) { gLog->debug("{:08x} {}", symbol->address, symbol->name); } } } return true; }
static int processFile(const char *fn, int dtype) { int rc = 1; int fdno = -1; struct stat st; GElf_Ehdr *ehdr, ehdr_mem; elfInfo *ei = rcalloc(1, sizeof(*ei)); fdno = open(fn, O_RDONLY); if (fdno < 0 || fstat(fdno, &st) < 0) goto exit; (void) elf_version(EV_CURRENT); ei->elf = elf_begin(fdno, ELF_C_READ, NULL); if (ei->elf == NULL || elf_kind(ei->elf) != ELF_K_ELF) goto exit; ehdr = gelf_getehdr(ei->elf, &ehdr_mem); if (ehdr == NULL) goto exit; if (ehdr->e_type == ET_DYN || ehdr->e_type == ET_EXEC) { ei->marker = mkmarker(ehdr); ei->isDSO = (ehdr->e_type == ET_DYN); ei->isExec = (st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)); processProgHeaders(ei, ehdr); processSections(ei); } /* * For DSOs which use the .gnu_hash section and don't have a .hash * section, we need to ensure that we have a new enough glibc. */ if (ei->isExec && ei->gotGNUHASH && !ei->gotHASH && !soname_only) { argvAdd(&ei->requires, "rtld(GNU_HASH)"); } /* * For DSOs, add DT_SONAME as provide. If its missing, we can fake * it from the basename if requested. The bizarre looking DT_DEBUG * check is used to avoid adding basename provides for PIE executables. */ if (ei->isDSO && !ei->gotDEBUG) { if (!ei->soname && fake_soname) { const char *bn = strrchr(fn, '/'); ei->soname = rstrdup(bn ? bn + 1 : fn); } if (ei->soname) addDep(&ei->provides, ei->soname, NULL, ei->marker); } /* If requested and present, add dep for interpreter (ie dynamic linker) */ if (ei->interp && require_interp) argvAdd(&ei->requires, ei->interp); rc = 0; /* dump the requested dependencies for this file */ for (ARGV_t dep = dtype ? ei->requires : ei->provides; dep && *dep; dep++) { fprintf(stdout, "%s\n", *dep); } exit: if (fdno >= 0) close(fdno); if (ei) { argvFree(ei->provides); argvFree(ei->requires); free(ei->soname); free(ei->interp); if (ei->elf) elf_end(ei->elf); rfree(ei); } return rc; }
int InfoRepoDiscovery::Config::discovery_config(ACE_Configuration_Heap& cf) { const ACE_Configuration_Section_Key& root = cf.root_section(); ACE_Configuration_Section_Key repo_sect; if (cf.open_section(root, REPO_SECTION_NAME, 0, repo_sect) != 0) { if (DCPS_debug_level > 0) { // This is not an error if the configuration file does not have // any repository (sub)section. The code default configuration will be used. ACE_DEBUG((LM_NOTICE, ACE_TEXT("(%P|%t) NOTICE: InfoRepoDiscovery::Config::discovery_config ") ACE_TEXT("failed to open [%s] section.\n"), REPO_SECTION_NAME)); } return 0; } else { // Ensure there are no properties in this section ValueMap vm; if (pullValues(cf, repo_sect, vm) > 0) { // There are values inside [repo] ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) InfoRepoDiscovery::Config::discovery_config ") ACE_TEXT("repo sections must have a subsection name\n")), -1); } // Process the subsections of this section (the individual repos) KeyList keys; if (processSections( cf, repo_sect, keys ) != 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) InfoRepoDiscovery::Config::discovery_config ") ACE_TEXT("too many nesting layers in the [repo] section.\n")), -1); } // Loop through the [repo/*] sections for (KeyList::const_iterator it=keys.begin(); it != keys.end(); ++it) { std::string repo_name = (*it).first; ValueMap values; pullValues( cf, (*it).second, values ); Discovery::RepoKey repoKey = Discovery::DEFAULT_REPO; bool repoKeySpecified = false, bitIpSpecified = false, bitPortSpecified = false; std::string repoIor; int bitPort = 0; std::string bitIp; for (ValueMap::const_iterator it=values.begin(); it != values.end(); ++it) { std::string name = (*it).first; if (name == "RepositoryKey") { repoKey = (*it).second; repoKeySpecified = true; if (DCPS_debug_level > 0) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) [repository/%C]: RepositoryKey == %C\n"), repo_name.c_str(), repoKey.c_str())); } } else if (name == "RepositoryIor") { repoIor = (*it).second; if (DCPS_debug_level > 0) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) [repository/%C]: RepositoryIor == %C\n"), repo_name.c_str(), repoIor.c_str())); } } else if (name == "DCPSBitTransportIPAddress") { bitIp = (*it).second; bitIpSpecified = true; if (DCPS_debug_level > 0) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) [repository/%C]: DCPSBitTransportIPAddress == %C\n"), repo_name.c_str(), bitIp.c_str())); } } else if (name == "DCPSBitTransportPort") { std::string value = (*it).second; bitPort = ACE_OS::atoi(value.c_str()); bitPortSpecified = true; if (convertToInteger(value, bitPort)) { } else { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) InfoRepoDiscovery::Config::discovery_config ") ACE_TEXT("Illegal integer value for DCPSBitTransportPort (%C) in [repository/%C] section.\n"), value.c_str(), repo_name.c_str()), -1); } if (DCPS_debug_level > 0) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) [repository/%C]: DCPSBitTransportPort == %d\n"), repo_name.c_str(), bitPort)); } } else { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) InfoRepoDiscovery::Config::discovery_config ") ACE_TEXT("Unexpected entry (%C) in [repository/%C] section.\n"), name.c_str(), repo_name.c_str()), -1); } } if (values.find("RepositoryIor") == values.end()) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) InfoRepoDiscovery::Config::discovery_config ") ACE_TEXT("Repository section [repository/%C] section is missing RepositoryIor value.\n"), repo_name.c_str()), -1); } if (!repoKeySpecified) { // If the RepositoryKey option was not specified, use the section // name as the repo key repoKey = repo_name; } InfoRepoDiscovery_rch discovery = new InfoRepoDiscovery(repoKey, repoIor.c_str()); if (bitPortSpecified) discovery->bit_transport_port(bitPort); if (bitIpSpecified) discovery->bit_transport_ip(bitIp); TheServiceParticipant->add_discovery( DCPS::static_rchandle_cast<Discovery>(discovery)); } } return 0; }