Do ELF object files store file system paths for dependent libraries? - ld

When we link executables with ld, we give a list of libraries that the executable depends upon. Is this the only source of the location information for these libraries, or is some information about the preferred version of dependent libraries stored as metadata in the object files?
The specific issue is this: If I link two dependent libraries lA and lB, which both depend upon a third library lC, and I place references to these libraries on the link line. It appears that C++ class methods in lA are calling into a different version of lC than class methods in lB. How is this possible? I know this from looking at a backtrace in gdb.

They might. DT_RPATH is used for symbol resolution. They also include the full object name, that might include a version number, and if the library uses versioning correctly, then the symbols don't actually collide with each other.
I can send you to my blog for a couple of insight into DT_RPATH and DT_SONAME:
https://blog.flameeyes.eu/2010/06/the-why-and-how-of-rpath/
https://blog.flameeyes.eu/2009/10/a-shared-library-by-any-other-name/
https://blog.flameeyes.eu/2010/10/linkers-and-names/

Related

Is there a difference in linking standard and custom dynamic library?

I don't get how standard library like libc is linked.I use MingW compiler.
I see that there is no libc.dll file in its bin folder.Then how libc is linked?
How does compiler know difference between custom and dynamic library?
We use build tools because they are a practical way to compile code and create executables, deployables etc.
For example. Consider that you have a large Java application consisting of thousands of separate source files split over multiple packages. Suppose that it has a number of JAR file dependencies, some of them for libraries that you have developed, and others for external libraries that can be downloaded from standard places.
You could spend hours manually downloading external JAR files and putting them in the right place. Then you could manually run javac for each of the source files, and jar in multiple times. Each time in the correct directory with the correct command line arguments ... and in the correct order.
And each time you change the source code ... repeat the relevant parts of the above process.
And make sure you don't make a mistake which will cause you to waste time finding test failures, runtime errors, etc caused by not building correctly.
Or ... you could use a build tool that takes care of it all. And does it correctly each time.
In summary, the reasons we use build tools are:
They are less work than doing it by hand
They are more accurate
The results are more reproducible.
I want to know why compiler can't do it?
Because compilers are not designed to perform the entire build process. Just like your oven is not designed to cook a three course meal and serve it up at the dinner table.
A compiler is (typically) designed to compile individual source code files. There is more to building than doing that.

Guids vs. Protocols in EDK2

I was trying to understand the different sections in the package declaration file (.dec) of an EDK2 module, however I can't seem to figure out why some GUID definitions are under the [GUIDs] section and some are under the [Protocols] section or [Ppis] section. Is there a reason why they should not be under the same section, especially from the perspective of the EDK2 build process?
So, this is half an answer at most, but:
A GUID, ultimately, is nothing other than a 128-bit value statistically guaranteed to be unique (if generated using the defined method).
The [Guids] section of the .dec defines GUIDs that point to generic data structures, variable namespaces, things...
The [Protocols] section defines discoverable UEFI APIs, whereas [Ppis] defines PEI (Pre-EFI) APIs.
Ultimately, this becomes relevant when processing module .inf files, which declare which [Guids], [Protocols] and [Ppis] they require to build. I.e., you could possibly get away with just declaring everything as GUIDs - but then you'd loose any sanity checking preventing you from using PPIs in DXE, or the other way around.

How to make "prereqs" of CPAN::Meta::Spec require a distribution instead of a package?

I'm researching about how to package some of my Perl apps and better manage their dependencies to make distribution easier for me and my customers, which most likely doesn't include uploading to CPAN at all. Instead, I would provide custom repos if necessary or, more likely, access to SCMs like Subversion.
CPAN::Meta::Spec seems to provide what I need to describe my apps, their dependencies and even where to get them from, but what I'm wondering is about the level of detail of pre-requisites. The spec contains the following sentence:
The set of relations must be specified as a Map of package names to version ranges.
Requiring packages seems a little too low level for my needs, I would prefer requiring distributions instead. Pretty much the level (from my understanding) tools like Maven and Gradle work at, e.g. Apache Commons Lang vs. Apache Commons IO etc. instead of individual classes like org.apache.commons.lang3.AnnotationUtils or org.apache.commons.io.ByteOrderMark. OTOH, the example in the docs contains the following lines:
requires => {
'perl' => '5.006',
'File::Spec' => '0.86',
'JSON' => '2.16',
},
The line containing perl doesn't look like a package to me and I didn't find some package perl or perl.pm anywhere on my system. Seems to me like that is handled differently to the other things of the example.
I have a system wide folder containing e.g. some utility packages, which seems comparable to some abstract perl to me. That folder should get defined as one distribution, maintain a version number for all of the packages in that folder and therefore should allow other apps to require that whole thing. If I understand the docs correctly, I would need to create not only the META.yml in the folder, but additionally some e.g. sysutils.pm containing package sysutils; and defining some version.
Is there some way to avoid creating that file and really require the distribution itself only?
The META.yml already contains a name and version on it's own, so looks like some abstract thing one could require in theory. I don't see the need of adding an additional .pm-file representing the distribution itself only to allow require to work. It wouldn't contain any business logic in my case.
Thanks!
That's really not what you want to do. You want to pre-req what you actually require. So, for example, if you need File::Spec, that's what you need, regardless of whether it comes from perl core or from a separate CPAN distribution.
I've seen cases where certain modules have moved from CPAN to core, or vice versa. By requiring the module directly, you don't need to ship new releases of your dependent distributions simply because someone you depend on changed their method of distribution.
I've also seen cases where certain modules are split off from their original distributions when it was determined they were valuable as standalone modules. Depending on the module means that you no longer drag in a bunch of other modules for a simple dependency.
What you're more or less looking for is akin to the Task::* modules. No real logic in most of them, just a list of further dependencies.
The Perl dependency system works entirely on package names, on multiple levels. When a CPAN distribution is uploaded, each package within is indexed by PAUSE, which also checks if the uploader has permissions for that package and that the package has a newer version than the currently indexed package. None of these checks care about the distribution as a whole (though the indexer does do other checks at that level).
Then, when a CPAN client sees a dependency, or you tell it to install something, it checks the index for that package name, which tells it what distribution release to install. If it depends on a certain version, that is checked against the $VERSION declared in that package if you have it installed; whereas once a distribution is installed, its "version" is no longer tracked. The distribution level is almost entirely meaningless except that it is what is ultimately downloaded and installed to satisfy these dependencies. This is important, because modules can and do move between distributions, maintaining their version increments, and the package index will always tell you which distribution to get the version you need.
As you noticed, the perl dependency is weird. It's a special case that has been there forever, as a convention to declare what version of Perl you require, you declare a runtime requirement of perl. It is not an indexed module, and every CPAN client and other consumer of CPAN metadata special cases this to either ignore it or treat it as a minimum Perl version, rather than something that can be installed. There's no way to extend this to work for distributions in general, and it would be a bad idea to try.
As an additional note, the CPAN meta spec is a specification for the file named META.json included in CPAN distributions (META.yml is the legacy version), but this file is automatically generated by your authoring tool. It should never be manually created, though you may have your authoring tool manually add certain keys (in which case reading the spec is important), including prereqs. See neilb's blog post for how to specify dependencies for various authoring tools, which will then transpose these into the generated META file, and also how to use cpanfiles to specify dependencies in general.

Finding class and function names from an x86-64 executable

I am wondering about if it is always possible, in some way to obtain the function and class names when reversing an application. (in this case a game) I have tried for around 1 month to reverse a game (Assassin's Creed Unity (anvil engine)) but still no luck getting the function names. I have found a way to obtain the class names but no clue on function names.
So my question is, is it possible to actually obtain the function name out having the documentation, and create a hierarchy. (I ame doing this to get better at reversing and to learn new things (asm x64))
Any tips and tricks related to reversing classes/structers are appreciated.
No, function and class names aren't needed for compiled code to work, and usually aren't part of an executable that's had its symbol table stripped.
The exception to that would be calls across DLL boundaries where you might get some mangled C++ names containing function and class names, or if there are any error-check / assert messages in the release build then some names might show up in strings.
C++ with RTTI (RunTime Type Info) might have type names somewhere, maybe mapping vtable pointers to strings, or for classes with no virtual members probably only if typeid was ever actually used. (Or not at all if compiled with RTTI disabled. activate RTTI in c++)
Even exception-handling I think doesn't need class names in the binary.
Other than that, there's no need for class names or function names in the compiled binary. Definitely not in the machine code itself; that's of course all pointers / relative offsets, even for classes with virtual functions. How do objects work in x86 at the assembly level?.
C++ does not generally support introspection, unlike Java, so there's no default need for any of the info you're looking for to be in the executable anywhere.

Identifying circular dependency between static libraries through script

I have a list of binaries that link some static libraries. It was identified that a bunch of these libraries are circular dependent. We never ran into troubles because we enclosed these static libraries between -Wl,--start-group, and -Wl,--end-group
Having understood that this is a bad practice, I'm trying to clean the system.
I've come up with a perl script that tells me how these libraries are dependent on each other, like so:
libchld.a depends on libprnt.a, libgprnt.a
libprnt.a depends on libncle.a, libgprnt.a
and goes one.
Now, I should sort these topologically with each node either pointing upwards or downwards.
And then If I find a set of cyclic dependent libraries while sorting topologically, I will have to enclose only those inside a --start-group and --end-group(than enclosing the entire bunch of libraries) there by cleaning up the system.
Are there some perl modules that does this type of sorting already?
Sort::Topological
Graph::Directed
are those I'm trying to check. But, they don't appear to handle if the graph is circular.
Having understood that this is a bad practice, I'm trying to clean the system.
It's a bad practice because you are not using proper layering, not because it's somehow bad for the linker.
Therefore, cleaning up the link line without re-arranging the libraries into a proper hierarchy with no circular dependencies is a pointless exercise.
And if you do rearrange the libraries, then their proper order will be easy to understand and you wouldn't need to use Perl for that.