WARNING: Like I said, this solution could destroy your OS if you’re not careful enough.
Reinstalling OS and all the VLSI-CAD tools is not fun. So, do it at your own risk.

I. Main Solution

  • Step 1: First of all, check your GLIBC version:
     $ ldd --version
    

    Example print-out:

     ldd (Ubuntu GLIBC 2.39-0ubuntu8.4) 2.39
    

    I’m using Ubuntu 24.04, and according to this, my GLIBC version is 2.39 .
    -> This means 2.39 is not working. So we have to downgrade it (or upgrade it, we don’t know yet).

  • Step 2: Note on the run file in the bin/ folder vs. the executable ELF file:
    The run file in a tool’s bin/ is usually a .sh file to set the environment. It will eventually call to the actual executable ELF file, but it is NOT the ELF file.
    -> To know where the ELF file is, the easiest way is to run the run file. -> The true PATH to the ELF file will shown in the error.
    -> The $ objdump command in the next step must point to the executable ELF file, NOT the run file.

  • Step 3: Sometimes the error says which version it is looking for, and sometimes it just says GLIBC_PRIVATE .
    -> Regardless of what it said, even if it stated which version, don’t believe it yet.
    We need to check it manually. The check command:
     $ objdump -T /path/to/the/executable/ELF/file | grep GLIBC_ | sed 's/.*GLIBC_\([.0-9]*\).*/\1/g' | sort -Vu
    

    Example print-out:

     2.2.5
     2.3
     2.3.2
     2.3.3
     2.3.4
     2.4
     2.6
     2.7
     2.11
    

    According to this example, the minimum required GLIBC version is 2.11 .
    -> Combined with the previous information in step 1, we now know we have to DOWNGRADE the GLIBC to the range: 2.39 > wanted-version >= 2.11.

Note 1: Downgrade or upgrade depends on what information you get from steps 1 and 3. In my example, this will be a downgrade, but it might be an upgrade on your machine.

Note 2: Remember, you checked only the executable ELF file. However, there may be more run/lib files behind, and they could request a more recent version of GLIBC.
-> So, don’t downgrade it too far, and if you have to upgrade it, upgrade only the requested version (not the latest).

From the website, we have 2.41 (the latest), 2.39 (Ubuntu24.04), 2.35 (Ubuntu22.04), 2.31 (Ubuntu20.04), 2.27 (Ubuntu18.04), and so on.

Let’s say, I know my tool was released around 2020. -> So, 2.31 (Ubuntu20.04) sounds reasonable. Let’s do that first.
-> And if that doesn’t work, we’ll try 2.27 (Ubuntu18.04), and so on.

Just note which version you want to get; you don’t need to download anything (yet).

From the previous step, we have already chosen Ubuntu20.04 (with GLIBC version 2.31).
-> So let’s download that Ubuntu 20.04LTS .iso image.

To mount the .iso file, usually just double-click is enough.
Then, go to the .iso mounted folder and navigate to the casper/ folder.
There, you will find the filesystem.squashfs file.
-> Open a new terminal from there, then do this to unsquash it to your Downloads/ folder:

   $ sudo unsquashfs -d ~/Downloads/unsquashfs filesystem.squashfs

This will unsquash all the .iso disc data to your ~/Downloads/unsquashfs folder.
Finally, let’s copy that data to our system in /usr/; let’s say, /usr/glibc-2.31 :

   $ sudo cp -rf ~/Downloads/unsquashfs/usr /usr/glibc-2.31

After this, you can now run the tool with the overridden $PATH and $LD_LIBRARY_PATH .

  • Step 6: Before running the tool with /usr/glibc-2.31/ , we need to modify the ELF file’s linker-PATH.

Because we’re going to mess with the ELF file, it’s better to save the original ELF file to another ELF file.
For example: $ cp ./finesim ./finesim.bak

To change the ELF file’s linker-PATH, use the command:

   $ patchelf --set-interpreter <linker-PATH> <filename>

For example:

   $ patchelf --set-interpreter /usr/glibc-2.31/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 ./finesim

Note: This patchelf --set-interpreter must point to the executable ELF file, NOT the run rile.

  • Step 7: Finally, we can run the tool with /usr/glibc-2.31/ .
    To do that, simply run the executable ELF file (NOT the run file) with overridden $PATH and $LD_LIBRARY_PATH, like this:
     $ PATH=/usr/glibc-2.31/bin LD_LIBRARY_PATH=/usr/glibc-2.31/lib/x86_64-linux-gnu ./finesim
    

    Note: This ./finesim is the executable ELF file, NOT the run file.

Previously, the error is like this:

   ./finesim: /lib/x86_64-linux-gnu/libpthread.so.0: version `GLIBC_PRIVATE' not found (required by ./finesim)

Now, the error looks like this:

   ./finesim: /usr/glibc-2.31/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by /lib/libncurses.so.5)

It is working. The libc.so.6 is already at the correct location at /usr/glibc-2.31/lib/x86_64-linux-gnu/ . So, it’s not about the libc.so.6 .
-> In the above example, libncurses.so.5 is the one that is missing in the /usr/glibc-2.31/ folder.

To deal with the missing .so files, follow the next step.

  • Step 8: For the missing .so files in the /usr/glibc-2.31/lib/x86_64-linux-gnu/ , first, let’s do a quick check and search for a similar name in the /usr/glibc-2.31/ (NOT in the lib/x86_64-linux-gnu/) folder:
     $ cd /usr/glibc-2.31/
     $ find . -name "<name>.so*"
    

    Sometimes, the missing .so files are still in the /usr/glibc-2.31/ , just not in the lib/x86_64-linux-gnu/ one.
    If that is the case, simply create a symbolic link in the /usr/glibc-2.31/lib/x86_64-linux-gnu/ .
    The command: $ sudo ln -s <source file> <destination file>

If a similar .so file is not found in /usr/glibc-2.31/ , let’s check the apt package in the next step.

Select the released Ubuntu version you want to download.
In my case, it is focal (20.04LTS) because I chose the GLIBC version 2.31 from Ubuntu20.04 in step 4.

Scroll down and hit “All packages” to display everything (this will take a while to load).

Like the error shown in the example (in step 7), the package I want to download is libncurses.so.5 .
-> So, I search for the name libncurses5 .
-> For libncurses5 , I found “libncurses5 (6.2-0ubuntu2.1 …“ seems good. -> So, let’s take it as an example.

When you go to the package page, you can see the “[list of files]” to confirm that the file you’re looking for is there.
-> Once you’re ready, select the link that fits your “Architecture” (in my case, amd64), and it’ll lead you to the download page.

On the download page, look for 3 info: the mirror link, the subdirectory, and the .deb filename.
-> Then, you can download it by:

   $ wget <mirror link>/<subdirectory>/<the .deb filename>

For example:

  $ wget security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libncurses5_6.2-0ubuntu2.1_amd64.deb

After downloading, DO NOT install it, just EXTRACT. The extract command:

   $ dpkg-deb -x <the .deb filename> <folder name>

For example:

  $ dpkg-deb -x libncurses5_6.2-0ubuntu2.1_amd64.deb libncurses5

In the next step, do not copy just one .so file.
Because those .so files are usually linked, let’s copy every .so files there.
To do that, use this command:

   $ find <folder name> -name "*.so*" -exec sudo cp '{}' <destination folder> ';'

For example:

   $ find libncurses5/ -name "*.so*" -exec sudo cp '{}' /usr/glibc-2.31/lib/x86_64-linux-gnu/ ';'

That’s done. Let’s try to run the tool again.
This time, it gets a new error:

   ./finesim: /lib/libtinfo.so.5: version `NCURSES_TINFO_5.6.20061217' not found (required by /usr/glibc-2.31/lib/x86_64-linux-gnu/libncurses.so.5)

Take a closer look, and you’ll see that the libncurses.so.5 is already at the correct location of /usr/glibc-2.31/lib/x86_64-linux-gnu/ .
-> So, it’s not about the libncurses.so.5 -> libtinfo.so.5 is the one that is missing.

You know what to do next: repeat the previous step and this step again, rinse and repeat until all the problems are gone.

  • Step 10: Once the executable ELF file (NOT the run file) can run with the overridden $PATH and $LD_LIBRARY_PATH , you can make it permanent in two ways:

a) The easiest way is to modify the ~/.bashrc , put in alias which records the whole command PATH=... LD_LIBRARY_PATH=... /path/to/the/executable/ELF/file . For example:

   alias finesim='PATH=/usr/glibc-2.31/bin LD_LIBRARY_PATH=/usr/glibc-2.31/lib/x86_64-linux-gnu/ ~/VLSI-CAD/Synopsys/finesim/Q-2020.03-SP1/finesim/platform/linux64/finesim'

-> This is the fastest way. However, it could miss some environment settings set up by the run file.

b) Therefore, the safe way is to modify the run file itself.
Because the run file is actually a .sh file, it will eventually call the executable ELF file somewhere in its content.
-> We have to find those places and replace them <command> with PATH=... LD_LIBRARY_PATH=... <command>.
This takes more effort but is the safest option.

II. Backup Solution

NOTE: This solution was abandoned because later, I discovered that downloading the Ubuntu .iso image and then unsquash it is faster than this solution.

However, this solution has an advantage.
-> This solution allows you to rebuild an OLDER version of GLIBC with the NEWER version of GCC/Binutils/Linux, while downloading the .iso image can only give you the OLDER version of everything.
-> This is why I keep this solution as a backup here.

Repeat the same steps 1 to 4 as in the other solution, then:

  • Step 5: Besides the GLIBC version, you also need other information such as Linux version, GCC version, and binutils version of your machine.
    -> By default, you WILL want to keep other things as same as your running machine.
    -> That would be perfect. So, let’s do that.

To check your Linux version:

   $ uname -a

Example print-out:

   Linux thuc-UEC 6.11.0-17-generic

To check your binutils version:

  $ ld -v

Example print-out:

   GNU ld (GNU Binutils for Ubuntu) 2.42

To check your GCC version:

  $ gcc --version

Example print-out:

  gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0

So, we have the following information: Linux 6.11.0, Binutils 2.42, and GCC 13.3.0 .
-> Note all of that, we’re moving to the actual action.

Basically, this is the tool that allows you to create a custom root filesystem.
-> It’ll build the whole thing, a whole package, all as one.
-> Less headache about mismatched versions between GCC, GLIBC, binutils, Linux, etc.

To make:

   $ git clone https://github.com/crosstool-ng/crosstool-ng
   $ cd crosstool-ng/
   $ mkdir install
   $ cd install/
   $ export CT_PREFIX=$(pwd)
   $ mkdir src
   $ cd ../
   $ ./bootstrap
   $ ./configure --prefix=$CT_PREFIX --enable-local
   $ make
   $ ./ct-ng x86_64-unknown-linux-gnu
   $ ./ct-ng menuconfig

After this, a GUI will come up. -> We need to modify several things in menuconfig :

a) Select Paths and misc options
-> Modify the Local tarballs directory from ${HOME}/src to ${CT_PREFIX}/src
-> Exit back outside.

b) Select Operating System
-> Select Version of linux
-> Pick the one that is EQUAL or OLDER than the one you choose in the previous step.
-> Exit back outside.

c) Select Binary utilities
-> Select Version of binutils
-> Pick the one that you choose in the previous step.
-> Exit back outside.

d) Select C-library
-> Select Version of glibc
-> Pick the one that you choose in the previous step.
-> Exit back outside.

e) Select C compiler
-> Select Version of gcc
-> Pick the one that you choose in the previous step.
-> Exit back outside.

Done, Save and Exit the GUI.
Final step, build it: (this gonna take a while)

   $ env -u LD_LIBRARY_PATH time ./ct-ng build CT_JOBS=`nproc`
  • Step 7: When the build is completed,
    the files you want are in: install/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sysroot

Let’s copy them to, like, /usr/glibc-2.31 :

   $ sudo cp -rf install/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sysroot /usr/glibc-2.31

Now, you can run your tool with the overridden $PATH and $LD_LIBRARY_PATH .
Note: If you want to rebuild the crosstool-ng, just remove the install/ and .build/ folders and start again.

The rest of this solution repeats the same steps 6 to 10 as in the other solution, with some differences:

a) The linker-PATH ld-linux-x86-64.so.2 is in the /usr/glibc-2.31/lib/ folder, NOT in the /usr/glibc-2.31/lib/x86_64-linux-gnu/ folder as in the other solution.

b) For the $PATH and $LD_LIBRARY_PATH , they should point to:

   PATH=/usr/test/usr/bin          #(instead of /usr/glibc-2.31/bin as in the other solution)
   LD_LIBRARY_PATH=/usr/test/lib   #(instead of /usr/glibc-2.31/lib/x86_64-linux-gnu as in the other solution)