Add the WindowsResourceCOFFWriter class for producing the final COFF after all parsing is done.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
llvm/include/llvm/Object/WindowsResource.h | ||
---|---|---|
52–54 ↗ | (On Diff #101850) | I don't think it is a good practice to declare a new type in a header in an anonymous namespace because (I believe it is intended to be an internal data type but) it is visible from everywhere that includes this file. You can just use std::vector<std::vector<T>>, no? It is actually more readable than Table<T> as the former type is obvious. |
58 ↗ | (On Diff #101850) | Enum classes must start with an uppercase letter. Also, = 0 is redundant. |
71 ↗ | (On Diff #101850) | You can just do return Suffix->Version >> 16; |
74 ↗ | (On Diff #101850) | and return Suffix->Version; |
llvm/lib/Object/WindowsResource.cpp | ||
137 ↗ | (On Diff #101850) | Remove this blank line. |
387–392 ↗ | (On Diff #101850) | I doubt you actually want to fill the timestamp field of the output file. If you do that, any build is no longer reproducible. You probably want to leave it zero. |
llvm/tools/llvm-cvtres/llvm-cvtres.cpp | ||
115–118 ↗ | (On Diff #101850) | bool Verbose = InputArgs.hasArg(OPT_VERBOSE); |
Fix bug with reloc symbol name being printed in decimal, not hex.
Also fixed some readability bugs.
llvm/include/llvm/Object/WindowsResource.h | ||
---|---|---|
52–54 ↗ | (On Diff #101850) | Okay, whichever is most readable. |
llvm/lib/Object/WindowsResource.cpp | ||
387–392 ↗ | (On Diff #101850) | Hmm isn't the timestamp important for incremental linking to work? I don't think it's important for builds to be reproducible, since we are testing our output with the llvm-readobj tool. |
llvm/lib/Object/WindowsResource.cpp | ||
---|---|---|
391 ↗ | (On Diff #101982) | Incremental linking sees file itself's timestamp instead of a timestamp field inside a file, no? Reproducible build is generally important in many use cases, and you don't want to break that property unless breaking it is absolutely necessary. It is so convenient if you can always create an identical output from the same source tree. |
llvm/lib/Object/WindowsResource.cpp | ||
---|---|---|
391 ↗ | (On Diff #101982) | The MS linker actually uses the time in the file. I learned this the hard way getting LLVM obj files compatible with LINK.exe |
llvm/include/llvm/Object/WindowsResource.h | ||
---|---|---|
127–128 ↗ | (On Diff #101982) | Maybe you can return ArrayRef<std::vector<uint8_t>> here? Similarly for other function. |
llvm/lib/Object/WindowsResource.cpp | ||
137–143 ↗ | (On Diff #101982) | I don't think emplace_back is a win here, but it makes the code a little mroe confusing. Can you change this to push_back? |
164–165 ↗ | (On Diff #101982) | If it's not a string node and it's not a data node, then what is it? |
165 ↗ | (On Diff #101982) | Can you just initialize these inline in the class definition so we don't need these here? |
170–178 ↗ | (On Diff #101982) | What happens if someone passes false here? Is it even valid to have a data node with a version and characteristics? These two constructors are really confusing. What do you think about making the constructors private and then adding static functions std::unique_ptr<TreeNode> createDataNode(uint16_t Major, uint16_t Minor, uint32_t Characteristics); etc? |
311 ↗ | (On Diff #101982) | ArrayRef? |
llvm/lib/Object/WindowsResource.cpp | ||
---|---|---|
391 ↗ | (On Diff #101982) | Shouldn't we do whatever MS does? |
llvm/lib/Object/WindowsResource.cpp | ||
---|---|---|
391 ↗ | (On Diff #101982) | If that's needed, then well, we have to do that. |
llvm/lib/Object/WindowsResource.cpp | ||
---|---|---|
164–165 ↗ | (On Diff #101982) | There are two types of nodes: those that point to data, and those that point to children nodes. In the later case, the node can be identified by either a string or an integer id. So if it's not a string node and not a data node, it's a non-data node identified by an integer id. I should probably make this distinction more clear in the constructors. I've changed it so that one constructor is always used for creating non-data nodes, an accepts a flag for making it a string node. The other constructor makes only data nodes. |
170–178 ↗ | (On Diff #101982) | Hmmm intuitively it would seem that only data nodes should have version and characteristics, however I've had trouble verifying this and I haven't been able to generate a .res file where the version and characteristics are set to anything other than zero. For now I think it's safe to assume that only nodes containing data would have a version and characteristic for that data specified. I've tried to make things more clear in the constructors by having one used only for making data nodes and one for all others. |
llvm/lib/Object/WindowsResource.cpp | ||
---|---|---|
170–178 ↗ | (On Diff #101982) | But now the constructor doesn't really express its intent clearly. A user can't tell from looking that that the 3 argument version is for data nodes etc. How about making the constructor private and having: static std::unique_ptr<TreeNode> creteStringNode(StringRef Str); static std::unique_ptr<TreeNode> creteStringNode(uint32_t StringId); static std::unique_ptr<TreeNode> createDataNode(uint16_t Major, uint16_t Minor, uint32_t Characteristics); |
llvm/lib/Object/WindowsResource.cpp | ||
---|---|---|
391 ↗ | (On Diff #101982) | I bet they support the /Brepro flag that CL.exe has. If they support it we could have it too and fill it with whatever value they do. IIRC, they use 0xFFFFFFFF in CL to make it so that it always looks "new". |
Refactored parser + node classes to make more sense, and hide interfaces that other classes should never access.
llvm/lib/Object/WindowsResource.cpp | ||
---|---|---|
170–178 ↗ | (On Diff #101982) | Okay I've added these functions to clarify when each type of node is made. In fact, nothing outside of the class should be able to create new nodes. This is because creating new nodes relies on being able to keep the data and string table indexes in sync with the actual data and strings in the order they are read. I've made all non-const functions private and added WindowsResourceParser as a friend class, since really TreeNode is a class it uses internally and they know how each other function. |